mirror of
https://codeberg.org/PGPainless/sop-java.git
synced 2024-09-26 02:01:41 +02:00
Compare commits
No commits in common. "main" and "8.0.0" have entirely different histories.
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,29 +0,0 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
**Version**
|
||||
<!-- What versions of the following libraries are you using? -->
|
||||
- `sop-java`:
|
||||
- `pgpainless-core`:
|
||||
- `bouncycastle`:
|
||||
|
||||
**To Reproduce**
|
||||
<!-- Steps to reproduce the behavior: -->
|
||||
```
|
||||
Example Code Block
|
||||
```
|
||||
|
||||
**Expected behavior**
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
**Additional context**
|
||||
<!-- Add any other context about the problem here. -->
|
|
@ -22,8 +22,3 @@ License: Apache-2.0
|
|||
Files: external-sop/src/main/resources/sop/testsuite/external/*
|
||||
Copyright: 2023 the original author or authors
|
||||
License: Apache-2.0
|
||||
|
||||
# Github Issue Templates
|
||||
Files: .github/ISSUE_TEMPLATE/*
|
||||
Copyright: 2024 the original author or authors
|
||||
License: Apache-2.0
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
steps:
|
||||
run:
|
||||
when:
|
||||
event: push
|
||||
image: gradle:7.6-jdk11-jammy
|
||||
commands:
|
||||
# Install Sequoia-SOP
|
|
@ -2,8 +2,6 @@
|
|||
# See https://reuse.software/
|
||||
steps:
|
||||
reuse:
|
||||
when:
|
||||
event: push
|
||||
image: fsfe/reuse:latest
|
||||
commands:
|
||||
- reuse lint
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -6,20 +6,6 @@ SPDX-License-Identifier: Apache-2.0
|
|||
|
||||
# Changelog
|
||||
|
||||
## 10.0.1-SNAPSHOT
|
||||
- Remove `label()` option from `Armor` operation
|
||||
- Fix exit code for 'Missing required option/parameter' error
|
||||
- Fix `revoke-key`: Allow for multiple invocations of `--with-key-password` option
|
||||
|
||||
## 10.0.0
|
||||
- Update implementation to [SOP Specification revision 10](https://www.ietf.org/archive/id/draft-dkg-openpgp-stateless-cli-10.html).
|
||||
- Throw `BadData` when passing KEYS where CERTS are expected
|
||||
- Introduce `sopv` interface subset with revision `1.0`
|
||||
- Add `sop version --sopv`
|
||||
|
||||
## 8.0.1
|
||||
- `decrypt`: Do not throw `NoSignature` exception (exit code 3) if `--verify-with` is provided, but `VERIFICATIONS` is empty.
|
||||
|
||||
## 8.0.0
|
||||
- Rewrote `sop-java` in Kotlin
|
||||
- Rewrote `sop-java-picocli` in Kotlin
|
||||
|
|
|
@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0
|
|||
# SOP for Java
|
||||
|
||||
[![status-badge](https://ci.codeberg.org/api/badges/PGPainless/sop-java/status.svg)](https://ci.codeberg.org/PGPainless/sop-java)
|
||||
[![Spec Revision: 10](https://img.shields.io/badge/Spec%20Revision-10-blue)](https://datatracker.ietf.org/doc/draft-dkg-openpgp-stateless-cli/10/)
|
||||
[![Spec Revision: 8](https://img.shields.io/badge/Spec%20Revision-8-blue)](https://datatracker.ietf.org/doc/draft-dkg-openpgp-stateless-cli/08/)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/pgpainless/sop-java/badge.svg?branch=main)](https://coveralls.io/github/pgpainless/sop-java?branch=main)
|
||||
[![REUSE status](https://api.reuse.software/badge/github.com/pgpainless/sop-java)](https://api.reuse.software/info/github.com/pgpainless/sop-java)
|
||||
|
||||
|
@ -25,8 +25,6 @@ The repository contains the following modules:
|
|||
* [sop-java](/sop-java) defines a set of Java interfaces describing the Stateless OpenPGP Protocol.
|
||||
* [sop-java-picocli](/sop-java-picocli) contains a wrapper application that transforms the `sop-java` API into a command line application
|
||||
compatible with the SOP-CLI specification.
|
||||
* [external-sop](/external-sop) contains an API implementation that can be used to forward API calls to a SOP executable,
|
||||
allowing to delegate the implementation logic to an arbitrary SOP CLI implementation.
|
||||
|
||||
## Known Implementations
|
||||
(Please expand!)
|
||||
|
|
|
@ -16,7 +16,7 @@ import sop.external.operation.*
|
|||
import sop.operation.*
|
||||
|
||||
/**
|
||||
* Implementation of the [SOP] API using an external SOP binary.
|
||||
* Implementation of the {@link SOP} API using an external SOP binary.
|
||||
*
|
||||
* Instantiate an [ExternalSOP] object for the given binary and the given [TempDirProvider] using
|
||||
* empty environment variables.
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package sop.external
|
||||
|
||||
import java.nio.file.Files
|
||||
import java.util.*
|
||||
import sop.SOPV
|
||||
import sop.external.ExternalSOP.TempDirProvider
|
||||
import sop.external.operation.DetachedVerifyExternal
|
||||
import sop.external.operation.InlineVerifyExternal
|
||||
import sop.external.operation.VersionExternal
|
||||
import sop.operation.DetachedVerify
|
||||
import sop.operation.InlineVerify
|
||||
import sop.operation.Version
|
||||
|
||||
/**
|
||||
* Implementation of the [SOPV] API subset using an external sopv/sop binary.
|
||||
*
|
||||
* Instantiate an [ExternalSOPV] object for the given binary and the given [TempDirProvider] using
|
||||
* empty environment variables.
|
||||
*
|
||||
* @param binaryName name / path of the sopv binary
|
||||
* @param tempDirProvider custom tempDirProvider
|
||||
*/
|
||||
class ExternalSOPV(
|
||||
private val binaryName: String,
|
||||
private val properties: Properties = Properties(),
|
||||
private val tempDirProvider: TempDirProvider = defaultTempDirProvider()
|
||||
) : SOPV {
|
||||
|
||||
override fun version(): Version = VersionExternal(binaryName, properties)
|
||||
|
||||
override fun detachedVerify(): DetachedVerify = DetachedVerifyExternal(binaryName, properties)
|
||||
|
||||
override fun inlineVerify(): InlineVerify =
|
||||
InlineVerifyExternal(binaryName, properties, tempDirProvider)
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Default implementation of the [TempDirProvider] which stores temporary files in the
|
||||
* systems temp dir ([Files.createTempDirectory]).
|
||||
*
|
||||
* @return default implementation
|
||||
*/
|
||||
@JvmStatic
|
||||
fun defaultTempDirProvider(): TempDirProvider {
|
||||
return TempDirProvider { Files.createTempDirectory("ext-sopv").toFile() }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ package sop.external.operation
|
|||
import java.io.InputStream
|
||||
import java.util.Properties
|
||||
import sop.Ready
|
||||
import sop.enums.ArmorLabel
|
||||
import sop.exception.SOPGPException
|
||||
import sop.external.ExternalSOP
|
||||
import sop.operation.Armor
|
||||
|
@ -17,6 +18,8 @@ class ArmorExternal(binary: String, environment: Properties) : Armor {
|
|||
private val commandList: MutableList<String> = mutableListOf(binary, "armor")
|
||||
private val envList: List<String> = ExternalSOP.propertiesToEnv(environment)
|
||||
|
||||
override fun label(label: ArmorLabel): Armor = apply { commandList.add("--label=$label") }
|
||||
|
||||
@Throws(SOPGPException.BadData::class)
|
||||
override fun data(data: InputStream): Ready =
|
||||
ExternalSOP.executeTransformingOperation(Runtime.getRuntime(), commandList, envList, data)
|
||||
|
|
|
@ -108,8 +108,8 @@ class DecryptExternal(
|
|||
finish(process)
|
||||
|
||||
val sessionKeyOutIn = FileInputStream(sessionKeyOut)
|
||||
var line: String? = readString(sessionKeyOutIn)
|
||||
val sessionKey = line?.let { l -> SessionKey.fromString(l.trim { it <= ' ' }) }
|
||||
var line = readString(sessionKeyOutIn)
|
||||
val sessionKey = SessionKey.fromString(line.trim { it <= ' ' })
|
||||
sessionKeyOutIn.close()
|
||||
sessionKeyOut.delete()
|
||||
|
||||
|
@ -118,7 +118,7 @@ class DecryptExternal(
|
|||
val verifyOutIn = FileInputStream(verifyOut)
|
||||
val reader = BufferedReader(InputStreamReader(verifyOutIn))
|
||||
while (reader.readLine().also { line = it } != null) {
|
||||
line?.let { verifications.add(Verification.fromString(it.trim())) }
|
||||
verifications.add(Verification.fromString(line.trim()))
|
||||
}
|
||||
reader.close()
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class EncryptExternal(
|
|||
override fun mode(mode: EncryptAs): Encrypt = apply { commandList.add("--as=$mode") }
|
||||
|
||||
override fun signWith(key: InputStream): Encrypt = apply {
|
||||
commandList.add("--sign-with=@ENV:SIGN_WITH_$argCounter")
|
||||
commandList.add("--sign-with@ENV:SIGN_WITH_$argCounter")
|
||||
envList.add("SIGN_WITH_$argCounter=${ExternalSOP.readString(key)}")
|
||||
argCounter += 1
|
||||
}
|
||||
|
|
|
@ -68,10 +68,6 @@ class VersionExternal(binary: String, environment: Properties) : Version {
|
|||
return null
|
||||
}
|
||||
|
||||
override fun getSopVVersion(): String {
|
||||
return executeForLines(commandList.plus("--sopv"))
|
||||
}
|
||||
|
||||
override fun getSopSpecVersion(): String {
|
||||
return executeForLines(commandList.plus("--sop-spec"))
|
||||
}
|
||||
|
|
|
@ -12,12 +12,15 @@ dependencies {
|
|||
testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion"
|
||||
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
|
||||
|
||||
// Testing Exit Codes in JUnit
|
||||
// https://todd.ginsberg.com/post/testing-system-exit/
|
||||
testImplementation "com.ginsberg:junit5-system-exit:$junitSysExitVersion"
|
||||
|
||||
// Mocking Components
|
||||
testImplementation "org.mockito:mockito-core:$mockitoVersion"
|
||||
|
||||
// SOP
|
||||
implementation(project(":sop-java"))
|
||||
testImplementation(testFixtures(project(":sop-java")))
|
||||
|
||||
// CLI
|
||||
implementation "info.picocli:picocli:$picocliVersion"
|
||||
|
|
|
@ -21,8 +21,6 @@ class SOPExceptionExitCodeMapper : IExitCodeExceptionMapper {
|
|||
// Unmatched subcommand
|
||||
SOPGPException.UnsupportedSubcommand.EXIT_CODE
|
||||
}
|
||||
} else if (exception is MissingParameterException) {
|
||||
SOPGPException.MissingArg.EXIT_CODE
|
||||
} else if (exception is ParameterException) {
|
||||
// Invalid option (e.g. `--as invalid`)
|
||||
SOPGPException.UnsupportedOption.EXIT_CODE
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package sop.cli.picocli
|
||||
|
||||
import java.util.*
|
||||
import kotlin.system.exitProcess
|
||||
import picocli.AutoComplete
|
||||
import picocli.CommandLine
|
||||
import sop.SOPV
|
||||
import sop.cli.picocli.commands.*
|
||||
import sop.exception.SOPGPException
|
||||
|
||||
@CommandLine.Command(
|
||||
name = "sopv",
|
||||
resourceBundle = "msg_sop",
|
||||
exitCodeOnInvalidInput = SOPGPException.UnsupportedSubcommand.EXIT_CODE,
|
||||
subcommands =
|
||||
[
|
||||
// Meta subcommands
|
||||
VersionCmd::class,
|
||||
// signature verification subcommands
|
||||
VerifyCmd::class,
|
||||
InlineVerifyCmd::class,
|
||||
// misc
|
||||
CommandLine.HelpCommand::class,
|
||||
AutoComplete.GenerateCompletion::class])
|
||||
class SopVCLI {
|
||||
|
||||
companion object {
|
||||
@JvmStatic private var sopvInstance: SOPV? = null
|
||||
|
||||
@JvmStatic
|
||||
fun getSopV(): SOPV =
|
||||
checkNotNull(sopvInstance) { cliMsg.getString("sop.error.runtime.no_backend_set") }
|
||||
|
||||
@JvmStatic
|
||||
fun setSopVInstance(sopv: SOPV?) {
|
||||
sopvInstance = sopv
|
||||
}
|
||||
|
||||
@JvmField var cliMsg: ResourceBundle = ResourceBundle.getBundle("msg_sop")
|
||||
|
||||
@JvmField var EXECUTABLE_NAME = "sopv"
|
||||
|
||||
@JvmField
|
||||
@CommandLine.Option(names = ["--stacktrace"], scope = CommandLine.ScopeType.INHERIT)
|
||||
var stacktrace = false
|
||||
|
||||
@JvmStatic
|
||||
fun main(vararg args: String) {
|
||||
val exitCode = execute(*args)
|
||||
if (exitCode != 0) {
|
||||
exitProcess(exitCode)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun execute(vararg args: String): Int {
|
||||
// Set locale
|
||||
CommandLine(InitLocale()).parseArgs(*args)
|
||||
|
||||
// Re-set bundle with updated locale
|
||||
cliMsg = ResourceBundle.getBundle("msg_sop")
|
||||
|
||||
return CommandLine(SopVCLI::class.java)
|
||||
.apply {
|
||||
// explicitly set help command resource bundle
|
||||
subcommands["help"]?.setResourceBundle(ResourceBundle.getBundle("msg_help"))
|
||||
// Hide generate-completion command
|
||||
subcommands["generate-completion"]?.commandSpec?.usageMessage()?.hidden(true)
|
||||
// overwrite executable name
|
||||
commandName = EXECUTABLE_NAME
|
||||
// setup exception handling
|
||||
executionExceptionHandler = SOPExecutionExceptionHandler()
|
||||
exitCodeExceptionMapper = SOPExceptionExitCodeMapper()
|
||||
isCaseInsensitiveEnumValuesAllowed = true
|
||||
}
|
||||
.execute(*args)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Control the locale.
|
||||
*
|
||||
* @see <a href="https://picocli.info/#_controlling_the_locale">Picocli Readme</a>
|
||||
*/
|
||||
@CommandLine.Command
|
||||
class InitLocale {
|
||||
@CommandLine.Option(names = ["-l", "--locale"], descriptionKey = "sop.locale")
|
||||
fun setLocale(locale: String) = Locale.setDefault(Locale(locale))
|
||||
|
||||
@CommandLine.Unmatched
|
||||
var remainder: MutableList<String> =
|
||||
mutableListOf() // ignore any other parameters and options in the first parsing phase
|
||||
}
|
||||
}
|
|
@ -85,10 +85,13 @@ class DecryptCmd : AbstractSopCmd() {
|
|||
@Throws(IOException::class)
|
||||
private fun writeVerifyOut(result: DecryptionResult) {
|
||||
verifyOut?.let {
|
||||
getOutput(it).use { out ->
|
||||
PrintWriter(out).use { pw ->
|
||||
result.verifications.forEach { verification -> pw.println(verification) }
|
||||
if (result.verifications.isEmpty()) {
|
||||
val errorMsg = getMsg("sop.error.runtime.no_verifiable_signature_found")
|
||||
throw NoSignature(errorMsg)
|
||||
}
|
||||
|
||||
getOutput(verifyOut).use { out ->
|
||||
PrintWriter(out).use { pw -> result.verifications.forEach { pw.println(it) } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ class RevokeKeyCmd : AbstractSopCmd() {
|
|||
|
||||
@Option(names = ["--no-armor"], negatable = true) var armor = true
|
||||
|
||||
@Option(names = ["--with-key-password"], paramLabel = "PASSWORD", arity = "0..*")
|
||||
var withKeyPassword: List<String> = listOf()
|
||||
@Option(names = ["--with-key-password"], paramLabel = "PASSWORD")
|
||||
var withKeyPassword: String? = null
|
||||
|
||||
override fun run() {
|
||||
val revokeKey = throwIfUnsupportedSubcommand(SopCLI.getSop().revokeKey(), "revoke-key")
|
||||
|
@ -29,9 +29,9 @@ class RevokeKeyCmd : AbstractSopCmd() {
|
|||
revokeKey.noArmor()
|
||||
}
|
||||
|
||||
for (passwordIn in withKeyPassword) {
|
||||
withKeyPassword?.let {
|
||||
try {
|
||||
val password = stringFromInputStream(getInput(passwordIn))
|
||||
val password = stringFromInputStream(getInput(it))
|
||||
revokeKey.withKeyPassword(password)
|
||||
} catch (e: SOPGPException.UnsupportedOption) {
|
||||
val errorMsg =
|
||||
|
|
|
@ -22,7 +22,6 @@ class VersionCmd : AbstractSopCmd() {
|
|||
@Option(names = ["--extended"]) var extended: Boolean = false
|
||||
@Option(names = ["--backend"]) var backend: Boolean = false
|
||||
@Option(names = ["--sop-spec"]) var sopSpec: Boolean = false
|
||||
@Option(names = ["--sopv"]) var sopv: Boolean = false
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
|
@ -48,10 +47,5 @@ class VersionCmd : AbstractSopCmd() {
|
|||
println(version.getSopSpecVersion())
|
||||
return
|
||||
}
|
||||
|
||||
if (exclusive!!.sopv) {
|
||||
println(version.getSopVVersion())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
usage.header=Add ASCII Armor to standard input
|
||||
label=Label to be used in the header and tail of the armoring
|
||||
|
||||
stacktrace=Print stacktrace
|
||||
# Generic TODO: Remove when bumping picocli to 4.7.0
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
usage.header=Schütze Standard-Eingabe mit ASCII Armor
|
||||
label=Label für Kopf- und Fußzeile der ASCII Armor
|
||||
|
||||
stacktrace=Stacktrace ausgeben
|
||||
# Generic TODO: Remove when bumping picocli to 4.7.0
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
sop.name=sop
|
||||
sopv.name=sopv
|
||||
usage.header=Stateless OpenPGP Protocol
|
||||
sopv.usage.header=Stateless OpenPGP Protocol - Signature Verification Interface Subset
|
||||
locale=Locale for description texts
|
||||
|
||||
# Generic
|
||||
|
@ -36,8 +34,6 @@ usage.exitCodeList.17=73:Ambiguous input (a filename matching the designator alr
|
|||
usage.exitCodeList.18=79:Key is not signing capable
|
||||
usage.exitCodeList.19=83:Options were supplied that are incompatible with each other
|
||||
usage.exitCodeList.20=89:The requested profile is unsupported, or the indicated subcommand does not accept profiles
|
||||
usage.exitCodeList.21=97:The implementation supports some form of hardware-backed secret keys, but could not identify the hardware device
|
||||
usage.exitCodeList.22=101:The implementation tried to use a hardware-backed secret key, but the cryptographic hardware refused the operation for some reason other than a bad PIN or password
|
||||
|
||||
## SHARED RESOURCES
|
||||
stacktrace=Print stacktrace
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
sop.name=sop
|
||||
sopv.name=sopv
|
||||
usage.header=Stateless OpenPGP Protocol
|
||||
sopv.usage.header=Stateless OpenPGP Protocol - Signature Verification Interface Subset
|
||||
locale=Gebietsschema für Beschreibungstexte
|
||||
|
||||
# Generic
|
||||
|
@ -36,8 +34,6 @@ usage.exitCodeList.17=73:Mehrdeutige Eingabe (ein Dateiname, der dem Bezeichner
|
|||
usage.exitCodeList.18=79:Schlüssel ist nicht fähig zu signieren
|
||||
usage.exitCodeList.19=83:Miteinander inkompatible Optionen spezifiziert
|
||||
usage.exitCodeList.20=89:Das angeforderte Profil wird nicht unterstützt, oder der angegebene Unterbefehl akzeptiert keine Profile
|
||||
usage.exitCodeList.21=97:Die Anwendung unterstützt hardwaregestützte private Schlüssel, aber kann das Gerät nicht identifizieren
|
||||
usage.exitCodeList.22=101:Die Anwendung versuchte, einen hardwaregestützten Schlüssel zu verwenden, aber das Gerät lehnte den Vorgang aus einem anderen Grund als einer falschen PIN oder einem falschen Passwort ab
|
||||
|
||||
## SHARED RESOURCES
|
||||
stacktrace=Stacktrace ausgeben
|
||||
|
|
|
@ -6,13 +6,12 @@ package sop.cli.picocli;
|
|||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertGenericError;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertUnsupportedSubcommand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sop.SOP;
|
||||
import sop.exception.SOPGPException;
|
||||
|
@ -35,18 +34,20 @@ import sop.operation.Version;
|
|||
public class SOPTest {
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedSubcommand.EXIT_CODE)
|
||||
public void assertExitOnInvalidSubcommand() {
|
||||
SOP sop = mock(SOP.class);
|
||||
SopCLI.setSopInstance(sop);
|
||||
|
||||
assertUnsupportedSubcommand(() -> SopCLI.execute("invalid"));
|
||||
SopCLI.main(new String[] {"invalid"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(1)
|
||||
public void assertThrowsIfNoSOPBackendSet() {
|
||||
SopCLI.setSopInstance(null);
|
||||
// At this point, no SOP backend is set, so an InvalidStateException triggers error code 1
|
||||
assertGenericError(() -> SopCLI.execute("armor"));
|
||||
// At this point, no SOP backend is set, so an InvalidStateException triggers exit(1)
|
||||
SopCLI.main(new String[] {"armor"});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package sop.cli.picocli.commands;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import com.ginsberg.junit.exit.FailOnSystemExit;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sop.Ready;
|
||||
|
@ -22,8 +24,6 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertBadData;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertSuccess;
|
||||
|
||||
public class ArmorCmdTest {
|
||||
|
||||
|
@ -42,22 +42,24 @@ public class ArmorCmdTest {
|
|||
|
||||
@Test
|
||||
public void assertDataIsAlwaysCalled() throws SOPGPException.BadData, IOException {
|
||||
assertSuccess(() -> SopCLI.execute("armor"));
|
||||
SopCLI.main(new String[] {"armor"});
|
||||
verify(armor, times(1)).data((InputStream) any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void ifBadDataExit41() throws SOPGPException.BadData, IOException {
|
||||
when(armor.data((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
|
||||
assertBadData(() -> SopCLI.execute("armor"));
|
||||
SopCLI.main(new String[] {"armor"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailOnSystemExit
|
||||
public void ifNoErrorsNoExit() {
|
||||
when(sop.armor()).thenReturn(armor);
|
||||
|
||||
assertSuccess(() -> SopCLI.execute("armor"));
|
||||
SopCLI.main(new String[] {"armor"});
|
||||
}
|
||||
|
||||
private static Ready nopReady() {
|
||||
|
|
|
@ -9,13 +9,12 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertBadData;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertSuccess;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sop.Ready;
|
||||
|
@ -49,13 +48,14 @@ public class DearmorCmdTest {
|
|||
|
||||
@Test
|
||||
public void assertDataIsCalled() throws IOException, SOPGPException.BadData {
|
||||
assertSuccess(() -> SopCLI.execute("dearmor"));
|
||||
SopCLI.main(new String[] {"dearmor"});
|
||||
verify(dearmor, times(1)).data((InputStream) any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void assertBadDataCausesExit41() throws IOException, SOPGPException.BadData {
|
||||
when(dearmor.data((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException("invalid armor")));
|
||||
assertBadData(() -> SopCLI.execute("dearmor"));
|
||||
SopCLI.main(new String[] {"dearmor"});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package sop.cli.picocli.commands;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
|
@ -20,7 +21,6 @@ import sop.operation.Decrypt;
|
|||
import sop.util.HexUtil;
|
||||
import sop.util.UTCUtil;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
|
@ -41,18 +41,6 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertBadData;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertCannotDecrypt;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertGenericError;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertIncompleteVerification;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertKeyIsProtected;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertMissingArg;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertMissingInput;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertOutputExists;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertPasswordNotHumanReadable;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertSuccess;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertUnsupportedAsymmetricAlgo;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertUnsupportedOption;
|
||||
|
||||
public class DecryptCmdTest {
|
||||
|
||||
|
@ -85,47 +73,47 @@ public class DecryptCmdTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingArg.EXIT_CODE)
|
||||
public void missingArgumentsExceptionCausesExit19() throws SOPGPException.MissingArg, SOPGPException.BadData, SOPGPException.CannotDecrypt, IOException {
|
||||
when(decrypt.ciphertext((InputStream) any())).thenThrow(new SOPGPException.MissingArg("Missing arguments."));
|
||||
assertMissingArg(() -> SopCLI.execute("decrypt"));
|
||||
SopCLI.main(new String[] {"decrypt"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void badDataExceptionCausesExit41() throws SOPGPException.MissingArg, SOPGPException.BadData, SOPGPException.CannotDecrypt, IOException {
|
||||
when(decrypt.ciphertext((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
assertBadData(() -> SopCLI.execute("decrypt"));
|
||||
SopCLI.main(new String[] {"decrypt"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.PasswordNotHumanReadable.EXIT_CODE)
|
||||
public void assertNotHumanReadablePasswordCausesExit31() throws SOPGPException.PasswordNotHumanReadable,
|
||||
SOPGPException.UnsupportedOption, IOException {
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("pretendThisIsNotReadable");
|
||||
when(decrypt.withPassword(any())).thenThrow(new SOPGPException.PasswordNotHumanReadable());
|
||||
assertPasswordNotHumanReadable(() ->
|
||||
SopCLI.execute("decrypt", "--with-password", passwordFile.getAbsolutePath())
|
||||
);
|
||||
SopCLI.main(new String[] {"decrypt", "--with-password", passwordFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertWithPasswordPassesPasswordDown() throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption, IOException {
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("orange");
|
||||
assertSuccess(() -> SopCLI.execute("decrypt", "--with-password", passwordFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt", "--with-password", passwordFile.getAbsolutePath()});
|
||||
verify(decrypt, times(1)).withPassword("orange");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void assertUnsupportedWithPasswordCausesExit37() throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption, IOException {
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("swordfish");
|
||||
when(decrypt.withPassword(any())).thenThrow(new SOPGPException.UnsupportedOption("Decrypting with password not supported."));
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("decrypt", "--with-password", passwordFile.getAbsolutePath())
|
||||
);
|
||||
SopCLI.main(new String[] {"decrypt", "--with-password", passwordFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertDefaultTimeRangesAreUsedIfNotOverwritten() throws SOPGPException.UnsupportedOption {
|
||||
Date now = new Date();
|
||||
assertSuccess(() -> SopCLI.execute("decrypt"));
|
||||
SopCLI.main(new String[] {"decrypt"});
|
||||
verify(decrypt, times(1)).verifyNotBefore(AbstractSopCmd.BEGINNING_OF_TIME);
|
||||
verify(decrypt, times(1)).verifyNotAfter(
|
||||
ArgumentMatchers.argThat(argument -> {
|
||||
|
@ -136,8 +124,7 @@ public class DecryptCmdTest {
|
|||
|
||||
@Test
|
||||
public void assertVerifyNotAfterAndBeforeDashResultsInMaxTimeRange() throws SOPGPException.UnsupportedOption {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("decrypt", "--verify-not-before", "-", "--verify-not-after", "-"));
|
||||
SopCLI.main(new String[] {"decrypt", "--verify-not-before", "-", "--verify-not-after", "-"});
|
||||
verify(decrypt, times(1)).verifyNotBefore(AbstractSopCmd.BEGINNING_OF_TIME);
|
||||
verify(decrypt, times(1)).verifyNotAfter(AbstractSopCmd.END_OF_TIME);
|
||||
}
|
||||
|
@ -150,57 +137,54 @@ public class DecryptCmdTest {
|
|||
return Math.abs(now.getTime() - argument.getTime()) <= 1000;
|
||||
};
|
||||
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("decrypt", "--verify-not-before", "now", "--verify-not-after", "now"));
|
||||
SopCLI.main(new String[] {"decrypt", "--verify-not-before", "now", "--verify-not-after", "now"});
|
||||
verify(decrypt, times(1)).verifyNotAfter(ArgumentMatchers.argThat(isMaxOneSecOff));
|
||||
verify(decrypt, times(1)).verifyNotBefore(ArgumentMatchers.argThat(isMaxOneSecOff));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(1)
|
||||
public void assertMalformedDateInNotBeforeCausesExit1() {
|
||||
// ParserException causes exit(1)
|
||||
assertGenericError(() ->
|
||||
SopCLI.execute("decrypt", "--verify-not-before", "invalid"));
|
||||
SopCLI.main(new String[] {"decrypt", "--verify-not-before", "invalid"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(1)
|
||||
public void assertMalformedDateInNotAfterCausesExit1() {
|
||||
// ParserException causes exit(1)
|
||||
assertGenericError(() ->
|
||||
SopCLI.execute("decrypt", "--verify-not-after", "invalid"));
|
||||
SopCLI.main(new String[] {"decrypt", "--verify-not-after", "invalid"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void assertUnsupportedNotAfterCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||
when(decrypt.verifyNotAfter(any())).thenThrow(
|
||||
new SOPGPException.UnsupportedOption("Setting upper signature date boundary not supported."));
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("decrypt", "--verify-not-after", "now"));
|
||||
when(decrypt.verifyNotAfter(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting upper signature date boundary not supported."));
|
||||
SopCLI.main(new String[] {"decrypt", "--verify-not-after", "now"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void assertUnsupportedNotBeforeCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||
when(decrypt.verifyNotBefore(any())).thenThrow(
|
||||
new SOPGPException.UnsupportedOption("Setting lower signature date boundary not supported."));
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("decrypt", "--verify-not-before", "now"));
|
||||
when(decrypt.verifyNotBefore(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting lower signature date boundary not supported."));
|
||||
SopCLI.main(new String[] {"decrypt", "--verify-not-before", "now"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.OutputExists.EXIT_CODE)
|
||||
public void assertExistingSessionKeyOutFileCausesExit59() throws IOException {
|
||||
File tempFile = File.createTempFile("existing-session-key-", ".tmp");
|
||||
tempFile.deleteOnExit();
|
||||
assertOutputExists(() ->
|
||||
SopCLI.execute("decrypt", "--session-key-out", tempFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt", "--session-key-out", tempFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void assertWhenSessionKeyCannotBeExtractedExit37() throws IOException {
|
||||
Path tempDir = Files.createTempDirectory("session-key-out-dir");
|
||||
File tempFile = new File(tempDir.toFile(), "session-key");
|
||||
tempFile.deleteOnExit();
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("decrypt", "--session-key-out", tempFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt", "--session-key-out", tempFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -225,10 +209,8 @@ public class DecryptCmdTest {
|
|||
File verificationsFile = new File(tempDir.toFile(), "verifications");
|
||||
File keyFile = new File(tempDir.toFile(), "key.asc");
|
||||
keyFile.createNewFile();
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("decrypt", "--session-key-out", sessionKeyFile.getAbsolutePath(),
|
||||
"--verifications-out", verificationsFile.getAbsolutePath(), "--verify-with",
|
||||
keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt", "--session-key-out", sessionKeyFile.getAbsolutePath(),
|
||||
"--verifications-out", verificationsFile.getAbsolutePath(), "--verify-with", keyFile.getAbsolutePath()});
|
||||
|
||||
ByteArrayOutputStream bytesInFile = new ByteArrayOutputStream();
|
||||
try (FileInputStream fileIn = new FileInputStream(sessionKeyFile)) {
|
||||
|
@ -258,49 +240,45 @@ public class DecryptCmdTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.CannotDecrypt.EXIT_CODE)
|
||||
public void assertUnableToDecryptExceptionResultsInExit29() throws SOPGPException.CannotDecrypt, SOPGPException.MissingArg, SOPGPException.BadData, IOException {
|
||||
when(decrypt.ciphertext((InputStream) any())).thenThrow(new SOPGPException.CannotDecrypt());
|
||||
assertCannotDecrypt(() ->
|
||||
SopCLI.execute("decrypt"));
|
||||
SopCLI.main(new String[] {"decrypt"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertNoVerificationsIsOkay() throws SOPGPException.CannotDecrypt, SOPGPException.MissingArg, SOPGPException.BadData, IOException {
|
||||
File tempFile = File.createTempFile("verify-with-", ".tmp");
|
||||
File verifyOut = new File(tempFile.getParent(), "verifications.out");
|
||||
verifyOut.deleteOnExit();
|
||||
@ExpectSystemExitWithStatus(SOPGPException.NoSignature.EXIT_CODE)
|
||||
public void assertNoSignatureExceptionCausesExit3() throws SOPGPException.CannotDecrypt, SOPGPException.MissingArg, SOPGPException.BadData, IOException {
|
||||
when(decrypt.ciphertext((InputStream) any())).thenReturn(new ReadyWithResult<DecryptionResult>() {
|
||||
@Override
|
||||
public DecryptionResult writeTo(@Nonnull OutputStream outputStream) throws SOPGPException.NoSignature {
|
||||
return new DecryptionResult(null, Collections.emptyList());
|
||||
public DecryptionResult writeTo(OutputStream outputStream) throws SOPGPException.NoSignature {
|
||||
throw new SOPGPException.NoSignature();
|
||||
}
|
||||
});
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("decrypt", "--verify-with", tempFile.getAbsolutePath(), "--verifications-out",
|
||||
verifyOut.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void badDataInVerifyWithCausesExit41() throws IOException, SOPGPException.BadData {
|
||||
when(decrypt.verifyWithCert((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
File tempFile = File.createTempFile("verify-with-", ".tmp");
|
||||
assertBadData(() ->
|
||||
SopCLI.execute("decrypt", "--verify-with", tempFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt", "--verify-with", tempFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingInput.EXIT_CODE)
|
||||
public void unexistentCertFileCausesExit61() {
|
||||
assertMissingInput(() ->
|
||||
SopCLI.execute("decrypt", "--verify-with", "invalid"));
|
||||
SopCLI.main(new String[] {"decrypt", "--verify-with", "invalid"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.OutputExists.EXIT_CODE)
|
||||
public void existingVerifyOutCausesExit59() throws IOException {
|
||||
File certFile = File.createTempFile("existing-verify-out-cert", ".asc");
|
||||
File existingVerifyOut = File.createTempFile("existing-verify-out", ".tmp");
|
||||
|
||||
assertOutputExists(() -> SopCLI.execute("decrypt", "--verifications-out",
|
||||
existingVerifyOut.getAbsolutePath(), "--verify-with", certFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt", "--verifications-out", existingVerifyOut.getAbsolutePath(), "--verify-with", certFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -324,9 +302,7 @@ public class DecryptCmdTest {
|
|||
}
|
||||
});
|
||||
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("decrypt", "--verifications-out", verifyOut.getAbsolutePath(),
|
||||
"--verify-with", certFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt", "--verifications-out", verifyOut.getAbsolutePath(), "--verify-with", certFile.getAbsolutePath()});
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(verifyOut))) {
|
||||
String line = reader.readLine();
|
||||
assertEquals("2021-07-11T20:58:23Z 1B66A707819A920925BC6777C3E0AFC0B2DFF862 C8CD564EBF8D7BBA90611D8D071773658BF6BF86", line);
|
||||
|
@ -341,64 +317,66 @@ public class DecryptCmdTest {
|
|||
File sessionKeyFile1 = TestFileUtil.writeTempStringFile(key1.toString());
|
||||
File sessionKeyFile2 = TestFileUtil.writeTempStringFile(key2.toString());
|
||||
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("decrypt",
|
||||
SopCLI.main(new String[] {"decrypt",
|
||||
"--with-session-key", sessionKeyFile1.getAbsolutePath(),
|
||||
"--with-session-key", sessionKeyFile2.getAbsolutePath()));
|
||||
"--with-session-key", sessionKeyFile2.getAbsolutePath()});
|
||||
verify(decrypt).withSessionKey(key1);
|
||||
verify(decrypt).withSessionKey(key2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(1)
|
||||
public void assertMalformedSessionKeysResultInExit1() throws IOException {
|
||||
File sessionKeyFile = TestFileUtil.writeTempStringFile("C7CBDAF42537776F12509B5168793C26B93294E5ABDFA73224FB0177123E9137");
|
||||
assertGenericError(() ->
|
||||
SopCLI.execute("decrypt",
|
||||
"--with-session-key", sessionKeyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt",
|
||||
"--with-session-key", sessionKeyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void assertBadDataInKeysResultsInExit41() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException {
|
||||
when(decrypt.withKey((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
File tempKeyFile = File.createTempFile("key-", ".tmp");
|
||||
assertBadData(() -> SopCLI.execute("decrypt", tempKeyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt", tempKeyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingInput.EXIT_CODE)
|
||||
public void assertKeyFileNotFoundCausesExit61() {
|
||||
assertMissingInput(() -> SopCLI.execute("decrypt", "nonexistent-key"));
|
||||
SopCLI.main(new String[] {"decrypt", "nonexistent-key"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.KeyIsProtected.EXIT_CODE)
|
||||
public void assertProtectedKeyCausesExit67() throws IOException, SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData {
|
||||
when(decrypt.withKey((InputStream) any())).thenThrow(new SOPGPException.KeyIsProtected());
|
||||
File tempKeyFile = File.createTempFile("key-", ".tmp");
|
||||
assertKeyIsProtected(() -> SopCLI.execute("decrypt", tempKeyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt", tempKeyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedAsymmetricAlgo.EXIT_CODE)
|
||||
public void assertUnsupportedAlgorithmExceptionCausesExit13() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException {
|
||||
when(decrypt.withKey((InputStream) any())).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo("Unsupported asymmetric algorithm.", new IOException()));
|
||||
File tempKeyFile = File.createTempFile("key-", ".tmp");
|
||||
assertUnsupportedAsymmetricAlgo(() ->
|
||||
SopCLI.execute("decrypt", tempKeyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"decrypt", tempKeyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingInput.EXIT_CODE)
|
||||
public void assertMissingPassphraseFileCausesExit61() {
|
||||
assertMissingInput(() ->
|
||||
SopCLI.execute("decrypt", "--with-password", "missing"));
|
||||
SopCLI.main(new String[] {"decrypt", "--with-password", "missing"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingInput.EXIT_CODE)
|
||||
public void assertMissingSessionKeyFileCausesExit61() {
|
||||
assertMissingInput(() ->
|
||||
SopCLI.execute("decrypt", "--with-session-key", "missing"));
|
||||
SopCLI.main(new String[] {"decrypt", "--with-session-key", "missing"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.IncompleteVerification.EXIT_CODE)
|
||||
public void verifyOutWithoutVerifyWithCausesExit23() {
|
||||
assertIncompleteVerification(() ->
|
||||
SopCLI.execute("decrypt", "--verifications-out", "out.file"));
|
||||
SopCLI.main(new String[] {"decrypt", "--verifications-out", "out.file"});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package sop.cli.picocli.commands;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -27,17 +28,6 @@ import static org.mockito.Mockito.never;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertBadData;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertCertCannotEncrypt;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertGenericError;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertKeyCannotSign;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertKeyIsProtected;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertMissingArg;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertMissingInput;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertPasswordNotHumanReadable;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertSuccess;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertUnsupportedAsymmetricAlgo;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertUnsupportedOption;
|
||||
|
||||
public class EncryptCmdTest {
|
||||
|
||||
|
@ -60,50 +50,48 @@ public class EncryptCmdTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void missingBothPasswordAndCertFileCausesMissingArg() {
|
||||
assertMissingArg(() ->
|
||||
SopCLI.execute("encrypt", "--no-armor"));
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingArg.EXIT_CODE)
|
||||
public void missingBothPasswordAndCertFileCauseExit19() {
|
||||
SopCLI.main(new String[] {"encrypt", "--no-armor"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void as_unsupportedEncryptAsCausesUnsupportedOption() throws SOPGPException.UnsupportedOption {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void as_unsupportedEncryptAsCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||
when(encrypt.mode(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting encryption mode not supported."));
|
||||
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("encrypt", "--as", "Binary"));
|
||||
SopCLI.main(new String[] {"encrypt", "--as", "Binary"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void as_invalidModeOptionCausesUnsupportedOption() {
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("encrypt", "--as", "invalid"));
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void as_invalidModeOptionCausesExit37() {
|
||||
SopCLI.main(new String[] {"encrypt", "--as", "invalid"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void as_modeIsPassedDown() throws SOPGPException.UnsupportedOption, IOException {
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("0rbit");
|
||||
for (EncryptAs mode : EncryptAs.values()) {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("encrypt", "--as", mode.name(),
|
||||
"--with-password", passwordFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", "--as", mode.name(), "--with-password", passwordFile.getAbsolutePath()});
|
||||
verify(encrypt, times(1)).mode(mode);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withPassword_notHumanReadablePasswordCausesPWNotHumanReadable() throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption, IOException {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.PasswordNotHumanReadable.EXIT_CODE)
|
||||
public void withPassword_notHumanReadablePasswordCausesExit31() throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption, IOException {
|
||||
when(encrypt.withPassword("pretendThisIsNotReadable")).thenThrow(new SOPGPException.PasswordNotHumanReadable());
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("pretendThisIsNotReadable");
|
||||
assertPasswordNotHumanReadable(() ->
|
||||
SopCLI.execute("encrypt", "--with-password", passwordFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", "--with-password", passwordFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withPassword_unsupportedWithPasswordCausesUnsupportedOption() throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption, IOException {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void withPassword_unsupportedWithPasswordCausesExit37() throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption, IOException {
|
||||
when(encrypt.withPassword(any())).thenThrow(new SOPGPException.UnsupportedOption("Encrypting with password not supported."));
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("orange");
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("encrypt", "--with-password", passwordFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", "--with-password", passwordFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -111,107 +99,99 @@ public class EncryptCmdTest {
|
|||
File keyFile1 = File.createTempFile("sign-with-1-", ".asc");
|
||||
File keyFile2 = File.createTempFile("sign-with-2-", ".asc");
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("password");
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("encrypt", "--with-password", passwordFile.getAbsolutePath(),
|
||||
"--sign-with", keyFile1.getAbsolutePath(),
|
||||
"--sign-with", keyFile2.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", "--with-password", passwordFile.getAbsolutePath(), "--sign-with", keyFile1.getAbsolutePath(), "--sign-with", keyFile2.getAbsolutePath()});
|
||||
verify(encrypt, times(2)).signWith((InputStream) any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void signWith_nonExistentKeyFileCausesMissingInput() {
|
||||
assertMissingInput(() ->
|
||||
SopCLI.execute("encrypt", "--with-password", "admin", "--sign-with", "nonExistent.asc"));
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingInput.EXIT_CODE)
|
||||
public void signWith_nonExistentKeyFileCausesExit61() {
|
||||
SopCLI.main(new String[] {"encrypt", "--with-password", "admin", "--sign-with", "nonExistent.asc"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void signWith_keyIsProtectedCausesKeyIsProtected() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.KeyIsProtected.EXIT_CODE)
|
||||
public void signWith_keyIsProtectedCausesExit67() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException {
|
||||
when(encrypt.signWith((InputStream) any())).thenThrow(new SOPGPException.KeyIsProtected());
|
||||
File keyFile = File.createTempFile("sign-with", ".asc");
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("starship");
|
||||
assertKeyIsProtected(() ->
|
||||
SopCLI.execute("encrypt", "--sign-with", keyFile.getAbsolutePath(),
|
||||
"--with-password", passwordFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", "--sign-with", keyFile.getAbsolutePath(), "--with-password", passwordFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void signWith_unsupportedAsymmetricAlgoCausesUnsupportedAsymAlgo() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedAsymmetricAlgo.EXIT_CODE)
|
||||
public void signWith_unsupportedAsymmetricAlgoCausesExit13() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException {
|
||||
when(encrypt.signWith((InputStream) any())).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo("Unsupported asymmetric algorithm.", new Exception()));
|
||||
File keyFile = File.createTempFile("sign-with", ".asc");
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("123456");
|
||||
assertUnsupportedAsymmetricAlgo(() ->
|
||||
SopCLI.execute("encrypt", "--with-password", passwordFile.getAbsolutePath(),
|
||||
"--sign-with", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", "--with-password", passwordFile.getAbsolutePath(), "--sign-with", keyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void signWith_certCannotSignCausesKeyCannotSign() throws IOException, SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.KeyCannotSign, SOPGPException.BadData {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.KeyCannotSign.EXIT_CODE)
|
||||
public void signWith_certCannotSignCausesExit79() throws IOException, SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.KeyCannotSign, SOPGPException.BadData {
|
||||
when(encrypt.signWith((InputStream) any())).thenThrow(new SOPGPException.KeyCannotSign());
|
||||
File keyFile = File.createTempFile("sign-with", ".asc");
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("dragon");
|
||||
assertKeyCannotSign(() ->
|
||||
SopCLI.execute("encrypt", "--with-password", passwordFile.getAbsolutePath(),
|
||||
"--sign-with", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", "--with-password", passwordFile.getAbsolutePath(), "--sign-with", keyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void signWith_badDataCausesBadData() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void signWith_badDataCausesExit41() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException {
|
||||
when(encrypt.signWith((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
File keyFile = File.createTempFile("sign-with", ".asc");
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("orange");
|
||||
assertBadData(() ->
|
||||
SopCLI.execute("encrypt", "--with-password", passwordFile.getAbsolutePath(),
|
||||
"--sign-with", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", "--with-password", passwordFile.getAbsolutePath(), "--sign-with", keyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cert_nonExistentCertFileCausesMissingInput() {
|
||||
assertMissingInput(() ->
|
||||
SopCLI.execute("encrypt", "invalid.asc"));
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingInput.EXIT_CODE)
|
||||
public void cert_nonExistentCertFileCausesExit61() {
|
||||
SopCLI.main(new String[] {"encrypt", "invalid.asc"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cert_unsupportedAsymmetricAlgorithmCausesUnsupportedAsymAlg() throws IOException, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotEncrypt, SOPGPException.BadData {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedAsymmetricAlgo.EXIT_CODE)
|
||||
public void cert_unsupportedAsymmetricAlgorithmCausesExit13() throws IOException, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotEncrypt, SOPGPException.BadData {
|
||||
when(encrypt.withCert((InputStream) any())).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo("Unsupported asymmetric algorithm.", new Exception()));
|
||||
File certFile = File.createTempFile("cert", ".asc");
|
||||
assertUnsupportedAsymmetricAlgo(() ->
|
||||
SopCLI.execute("encrypt", certFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", certFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cert_certCannotEncryptCausesCertCannotEncrypt() throws IOException, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotEncrypt, SOPGPException.BadData {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.CertCannotEncrypt.EXIT_CODE)
|
||||
public void cert_certCannotEncryptCausesExit17() throws IOException, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotEncrypt, SOPGPException.BadData {
|
||||
when(encrypt.withCert((InputStream) any())).thenThrow(new SOPGPException.CertCannotEncrypt("Certificate cannot encrypt.", new Exception()));
|
||||
File certFile = File.createTempFile("cert", ".asc");
|
||||
assertCertCannotEncrypt(() ->
|
||||
SopCLI.execute("encrypt", certFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", certFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cert_badDataCausesBadData() throws IOException, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotEncrypt, SOPGPException.BadData {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void cert_badDataCausesExit41() throws IOException, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotEncrypt, SOPGPException.BadData {
|
||||
when(encrypt.withCert((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
File certFile = File.createTempFile("cert", ".asc");
|
||||
assertBadData(() ->
|
||||
SopCLI.execute("encrypt", certFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", certFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noArmor_notCalledByDefault() throws IOException {
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("clownfish");
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("encrypt", "--with-password", passwordFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", "--with-password", passwordFile.getAbsolutePath()});
|
||||
verify(encrypt, never()).noArmor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noArmor_callGetsPassedDown() throws IOException {
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("monkey");
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("encrypt", "--with-password", passwordFile.getAbsolutePath(), "--no-armor"));
|
||||
SopCLI.main(new String[] {"encrypt", "--with-password", passwordFile.getAbsolutePath(), "--no-armor"});
|
||||
verify(encrypt, times(1)).noArmor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeTo_ioExceptionCausesGenericError() throws IOException {
|
||||
@ExpectSystemExitWithStatus(1)
|
||||
public void writeTo_ioExceptionCausesExit1() throws IOException {
|
||||
when(encrypt.plaintext((InputStream) any())).thenReturn(new ReadyWithResult<EncryptionResult>() {
|
||||
@Override
|
||||
public EncryptionResult writeTo(@NotNull OutputStream outputStream) throws IOException, SOPGPException {
|
||||
|
@ -219,7 +199,6 @@ public class EncryptCmdTest {
|
|||
}
|
||||
});
|
||||
File passwordFile = TestFileUtil.writeTempStringFile("wildcat");
|
||||
assertGenericError(() ->
|
||||
SopCLI.execute("encrypt", "--with-password", passwordFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"encrypt", "--with-password", passwordFile.getAbsolutePath()});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,12 @@ import static org.mockito.Mockito.never;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertBadData;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertGenericError;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertSuccess;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sop.Ready;
|
||||
|
@ -47,34 +45,32 @@ public class ExtractCertCmdTest {
|
|||
|
||||
@Test
|
||||
public void noArmor_notCalledByDefault() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("extract-cert"));
|
||||
SopCLI.main(new String[] {"extract-cert"});
|
||||
verify(extractCert, never()).noArmor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noArmor_passedDown() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("extract-cert", "--no-armor"));
|
||||
SopCLI.main(new String[] {"extract-cert", "--no-armor"});
|
||||
verify(extractCert, times(1)).noArmor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void key_ioExceptionCausesGenericError() throws IOException, SOPGPException.BadData {
|
||||
@ExpectSystemExitWithStatus(1)
|
||||
public void key_ioExceptionCausesExit1() throws IOException, SOPGPException.BadData {
|
||||
when(extractCert.key((InputStream) any())).thenReturn(new Ready() {
|
||||
@Override
|
||||
public void writeTo(OutputStream outputStream) throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
});
|
||||
assertGenericError(() ->
|
||||
SopCLI.execute("extract-cert"));
|
||||
SopCLI.main(new String[] {"extract-cert"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void key_badDataCausesBadData() throws IOException, SOPGPException.BadData {
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void key_badDataCausesExit41() throws IOException, SOPGPException.BadData {
|
||||
when(extractCert.key((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
assertBadData(() ->
|
||||
SopCLI.execute("extract-cert"));
|
||||
SopCLI.main(new String[] {"extract-cert"});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,11 @@ import static org.mockito.Mockito.never;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertGenericError;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertMissingArg;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertSuccess;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertUnsupportedAsymmetricAlgo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
@ -50,22 +47,19 @@ public class GenerateKeyCmdTest {
|
|||
|
||||
@Test
|
||||
public void noArmor_notCalledByDefault() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("generate-key", "Alice"));
|
||||
SopCLI.main(new String[] {"generate-key", "Alice"});
|
||||
verify(generateKey, never()).noArmor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noArmor_passedDown() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("generate-key", "--no-armor", "Alice"));
|
||||
SopCLI.main(new String[] {"generate-key", "--no-armor", "Alice"});
|
||||
verify(generateKey, times(1)).noArmor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userId_multipleUserIdsPassedDownInProperOrder() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("generate-key", "Alice <alice@pgpainless.org>", "Bob <bob@pgpainless.org>"));
|
||||
SopCLI.main(new String[] {"generate-key", "Alice <alice@pgpainless.org>", "Bob <bob@pgpainless.org>"});
|
||||
|
||||
InOrder inOrder = Mockito.inOrder(generateKey);
|
||||
inOrder.verify(generateKey).userId("Alice <alice@pgpainless.org>");
|
||||
|
@ -75,32 +69,30 @@ public class GenerateKeyCmdTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingArg.EXIT_CODE)
|
||||
public void missingArgumentCausesExit19() throws SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.MissingArg, IOException {
|
||||
// TODO: RFC4880-bis and the current Stateless OpenPGP CLI spec allow keys to have no user-ids,
|
||||
// so we might want to change this test in the future.
|
||||
when(generateKey.generate()).thenThrow(new SOPGPException.MissingArg("Missing user-id."));
|
||||
assertMissingArg(() ->
|
||||
SopCLI.execute("generate-key"));
|
||||
SopCLI.main(new String[] {"generate-key"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedAsymmetricAlgo.EXIT_CODE)
|
||||
public void unsupportedAsymmetricAlgorithmCausesExit13() throws SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.MissingArg, IOException {
|
||||
when(generateKey.generate()).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo("Unsupported asymmetric algorithm.", new Exception()));
|
||||
assertUnsupportedAsymmetricAlgo(() ->
|
||||
SopCLI.execute("generate-key", "Alice"));
|
||||
|
||||
SopCLI.main(new String[] {"generate-key", "Alice"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ioExceptionCausesGenericError() throws SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.MissingArg, IOException {
|
||||
@ExpectSystemExitWithStatus(1)
|
||||
public void ioExceptionCausesExit1() throws SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.MissingArg, IOException {
|
||||
when(generateKey.generate()).thenReturn(new Ready() {
|
||||
@Override
|
||||
public void writeTo(OutputStream outputStream) throws IOException {
|
||||
throw new IOException();
|
||||
}
|
||||
});
|
||||
|
||||
assertGenericError(() ->
|
||||
SopCLI.execute("generate-key", "Alice"));
|
||||
SopCLI.main(new String[] {"generate-key", "Alice"});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package sop.cli.picocli.commands;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sop.ReadyWithResult;
|
||||
|
@ -25,8 +26,6 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertMissingArg;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertSuccess;
|
||||
|
||||
public class InlineDetachCmdTest {
|
||||
|
||||
|
@ -42,9 +41,9 @@ public class InlineDetachCmdTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testMissingSignaturesOutResultsInMissingArg() {
|
||||
assertMissingArg(() ->
|
||||
SopCLI.execute("inline-detach"));
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingArg.EXIT_CODE)
|
||||
public void testMissingSignaturesOutResultsInExit19() {
|
||||
SopCLI.main(new String[] {"inline-detach"});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -68,8 +67,7 @@ public class InlineDetachCmdTest {
|
|||
}
|
||||
});
|
||||
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("inline-detach", "--signatures-out", tempFile.getAbsolutePath(), "--no-armor"));
|
||||
SopCLI.main(new String[] {"inline-detach", "--signatures-out", tempFile.getAbsolutePath(), "--no-armor"});
|
||||
verify(inlineDetach, times(1)).noArmor();
|
||||
verify(inlineDetach, times(1)).message((InputStream) any());
|
||||
}
|
||||
|
|
|
@ -10,20 +10,13 @@ import static org.mockito.Mockito.never;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertBadData;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertExpectedText;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertGenericError;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertKeyIsProtected;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertMissingArg;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertMissingInput;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertSuccess;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertUnsupportedOption;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sop.ReadyWithResult;
|
||||
|
@ -61,77 +54,70 @@ public class SignCmdTest {
|
|||
|
||||
@Test
|
||||
public void as_optionsAreCaseInsensitive() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("sign", "--as", "Binary", keyFile.getAbsolutePath()));
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("sign", "--as", "binary", keyFile.getAbsolutePath()));
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("sign", "--as", "BINARY", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"sign", "--as", "Binary", keyFile.getAbsolutePath()});
|
||||
SopCLI.main(new String[] {"sign", "--as", "binary", keyFile.getAbsolutePath()});
|
||||
SopCLI.main(new String[] {"sign", "--as", "BINARY", keyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void as_invalidOptionCausesExit37() {
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("sign", "--as", "Invalid", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"sign", "--as", "Invalid", keyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void as_unsupportedOptionCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||
when(detachedSign.mode(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting signing mode not supported."));
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("sign", "--as", "binary", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"sign", "--as", "binary", keyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingInput.EXIT_CODE)
|
||||
public void key_nonExistentKeyFileCausesExit61() {
|
||||
assertMissingInput(() ->
|
||||
SopCLI.execute("sign", "invalid.asc"));
|
||||
SopCLI.main(new String[] {"sign", "invalid.asc"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.KeyIsProtected.EXIT_CODE)
|
||||
public void key_keyIsProtectedCausesExit67() throws SOPGPException.KeyIsProtected, IOException, SOPGPException.BadData {
|
||||
when(detachedSign.key((InputStream) any())).thenThrow(new SOPGPException.KeyIsProtected());
|
||||
assertKeyIsProtected(() ->
|
||||
SopCLI.execute("sign", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"sign", keyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void key_badDataCausesExit41() throws SOPGPException.KeyIsProtected, IOException, SOPGPException.BadData {
|
||||
when(detachedSign.key((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
assertBadData(() ->
|
||||
SopCLI.execute("sign", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"sign", keyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingArg.EXIT_CODE)
|
||||
public void key_missingKeyFileCausesExit19() {
|
||||
assertMissingArg(() ->
|
||||
SopCLI.execute("sign"));
|
||||
SopCLI.main(new String[] {"sign"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noArmor_notCalledByDefault() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("sign", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"sign", keyFile.getAbsolutePath()});
|
||||
verify(detachedSign, never()).noArmor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noArmor_passedDown() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("sign", "--no-armor", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"sign", "--no-armor", keyFile.getAbsolutePath()});
|
||||
verify(detachedSign, times(1)).noArmor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withKeyPassword_passedDown() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("sign",
|
||||
"--with-key-password", passFile.getAbsolutePath(),
|
||||
keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"sign", "--with-key-password", passFile.getAbsolutePath(), keyFile.getAbsolutePath()});
|
||||
verify(detachedSign, times(1)).withKeyPassword("sw0rdf1sh");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(1)
|
||||
public void data_ioExceptionCausesExit1() throws IOException, SOPGPException.ExpectedText {
|
||||
when(detachedSign.data((InputStream) any())).thenReturn(new ReadyWithResult<SigningResult>() {
|
||||
@Override
|
||||
|
@ -139,14 +125,13 @@ public class SignCmdTest {
|
|||
throw new IOException();
|
||||
}
|
||||
});
|
||||
assertGenericError(() ->
|
||||
SopCLI.execute("sign", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"sign", keyFile.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.ExpectedText.EXIT_CODE)
|
||||
public void data_expectedTextExceptionCausesExit53() throws IOException, SOPGPException.ExpectedText {
|
||||
when(detachedSign.data((InputStream) any())).thenThrow(new SOPGPException.ExpectedText());
|
||||
assertExpectedText(() ->
|
||||
SopCLI.execute("sign", keyFile.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"sign", keyFile.getAbsolutePath()});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,6 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertBadData;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertMissingInput;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertNoSignature;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertSuccess;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertUnsupportedOption;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
|
@ -26,6 +21,7 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -80,75 +76,60 @@ public class VerifyCmdTest {
|
|||
@Test
|
||||
public void notAfter_passedDown() throws SOPGPException.UnsupportedOption, ParseException {
|
||||
Date date = UTCUtil.parseUTCDate("2019-10-29T18:36:45Z");
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("verify", "--not-after", "2019-10-29T18:36:45Z",
|
||||
signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", "--not-after", "2019-10-29T18:36:45Z", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
verify(detachedVerify, times(1)).notAfter(date);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notAfter_now() throws SOPGPException.UnsupportedOption {
|
||||
Date now = new Date();
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("verify", "--not-after", "now",
|
||||
signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", "--not-after", "now", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
verify(detachedVerify, times(1)).notAfter(dateMatcher(now));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notAfter_dashCountsAsEndOfTime() throws SOPGPException.UnsupportedOption {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("verify", "--not-after", "-",
|
||||
signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", "--not-after", "-", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
verify(detachedVerify, times(1)).notAfter(AbstractSopCmd.END_OF_TIME);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void notAfter_unsupportedOptionCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||
when(detachedVerify.notAfter(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting upper signature date boundary not supported."));
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("verify", "--not-after", "2019-10-29T18:36:45Z",
|
||||
signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", "--not-after", "2019-10-29T18:36:45Z", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notBefore_passedDown() throws SOPGPException.UnsupportedOption, ParseException {
|
||||
Date date = UTCUtil.parseUTCDate("2019-10-29T18:36:45Z");
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("verify", "--not-before", "2019-10-29T18:36:45Z",
|
||||
signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", "--not-before", "2019-10-29T18:36:45Z", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
verify(detachedVerify, times(1)).notBefore(date);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notBefore_now() throws SOPGPException.UnsupportedOption {
|
||||
Date now = new Date();
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("verify", "--not-before", "now",
|
||||
signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", "--not-before", "now", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
verify(detachedVerify, times(1)).notBefore(dateMatcher(now));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notBefore_dashCountsAsBeginningOfTime() throws SOPGPException.UnsupportedOption {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("verify", "--not-before", "-",
|
||||
signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", "--not-before", "-", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
verify(detachedVerify, times(1)).notBefore(AbstractSopCmd.BEGINNING_OF_TIME);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void notBefore_unsupportedOptionCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||
when(detachedVerify.notBefore(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting lower signature date boundary not supported."));
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("verify", "--not-before", "2019-10-29T18:36:45Z",
|
||||
signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", "--not-before", "2019-10-29T18:36:45Z", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notBeforeAndNotAfterAreCalledWithDefaultValues() throws SOPGPException.UnsupportedOption {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("verify", signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
verify(detachedVerify, times(1)).notAfter(dateMatcher(new Date()));
|
||||
verify(detachedVerify, times(1)).notBefore(AbstractSopCmd.BEGINNING_OF_TIME);
|
||||
}
|
||||
|
@ -158,43 +139,43 @@ public class VerifyCmdTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingInput.EXIT_CODE)
|
||||
public void cert_fileNotFoundCausesExit61() {
|
||||
assertMissingInput(() ->
|
||||
SopCLI.execute("verify", signature.getAbsolutePath(), "invalid.asc"));
|
||||
SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), "invalid.asc"});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void cert_badDataCausesExit41() throws SOPGPException.BadData, IOException {
|
||||
when(detachedVerify.cert((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
assertBadData(() ->
|
||||
SopCLI.execute("verify", signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.MissingInput.EXIT_CODE)
|
||||
public void signature_fileNotFoundCausesExit61() {
|
||||
assertMissingInput(() ->
|
||||
SopCLI.execute("verify", "invalid.sig", cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", "invalid.sig", cert.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void signature_badDataCausesExit41() throws SOPGPException.BadData, IOException {
|
||||
when(detachedVerify.signatures((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
assertBadData(() ->
|
||||
SopCLI.execute("verify", signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.NoSignature.EXIT_CODE)
|
||||
public void data_noSignaturesCausesExit3() throws SOPGPException.NoSignature, IOException, SOPGPException.BadData {
|
||||
when(detachedVerify.data((InputStream) any())).thenThrow(new SOPGPException.NoSignature());
|
||||
assertNoSignature(() ->
|
||||
SopCLI.execute("verify", signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.BadData.EXIT_CODE)
|
||||
public void data_badDataCausesExit41() throws SOPGPException.NoSignature, IOException, SOPGPException.BadData {
|
||||
when(detachedVerify.data((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
|
||||
assertBadData(() ->
|
||||
SopCLI.execute("verify", signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -211,8 +192,7 @@ public class VerifyCmdTest {
|
|||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
System.setOut(new PrintStream(out));
|
||||
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("verify", signature.getAbsolutePath(), cert.getAbsolutePath()));
|
||||
SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), cert.getAbsolutePath()});
|
||||
|
||||
System.setOut(originalSout);
|
||||
|
||||
|
|
|
@ -4,18 +4,18 @@
|
|||
|
||||
package sop.cli.picocli.commands;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sop.SOP;
|
||||
import sop.cli.picocli.SopCLI;
|
||||
import sop.operation.Version;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertSuccess;
|
||||
import static sop.testsuite.assertions.SopExecutionAssertions.assertUnsupportedOption;
|
||||
|
||||
import com.ginsberg.junit.exit.ExpectSystemExitWithStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import sop.SOP;
|
||||
import sop.cli.picocli.SopCLI;
|
||||
import sop.exception.SOPGPException;
|
||||
import sop.operation.Version;
|
||||
|
||||
public class VersionCmdTest {
|
||||
|
||||
|
@ -29,8 +29,6 @@ public class VersionCmdTest {
|
|||
when(version.getVersion()).thenReturn("1.0");
|
||||
when(version.getExtendedVersion()).thenReturn("MockSop Extended Version Information");
|
||||
when(version.getBackendVersion()).thenReturn("Foo");
|
||||
when(version.getSopSpecVersion()).thenReturn("draft-dkg-openpgp-stateless-cli-XX");
|
||||
when(version.getSopVVersion()).thenReturn("1.0");
|
||||
when(sop.version()).thenReturn(version);
|
||||
|
||||
SopCLI.setSopInstance(sop);
|
||||
|
@ -38,41 +36,26 @@ public class VersionCmdTest {
|
|||
|
||||
@Test
|
||||
public void assertVersionCommandWorks() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("version"));
|
||||
SopCLI.main(new String[] {"version"});
|
||||
verify(version, times(1)).getVersion();
|
||||
verify(version, times(1)).getName();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertExtendedVersionCommandWorks() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("version", "--extended"));
|
||||
SopCLI.main(new String[] {"version", "--extended"});
|
||||
verify(version, times(1)).getExtendedVersion();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertBackendVersionCommandWorks() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("version", "--backend"));
|
||||
SopCLI.main(new String[] {"version", "--backend"});
|
||||
verify(version, times(1)).getBackendVersion();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertSpecVersionCommandWorks() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("version", "--sop-spec"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertSOPVVersionCommandWorks() {
|
||||
assertSuccess(() ->
|
||||
SopCLI.execute("version", "--sopv"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ExpectSystemExitWithStatus(SOPGPException.UnsupportedOption.EXIT_CODE)
|
||||
public void assertInvalidOptionResultsInExit37() {
|
||||
assertUnsupportedOption(() ->
|
||||
SopCLI.execute("version", "--invalid"));
|
||||
SopCLI.main(new String[] {"version", "--invalid"});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,13 +9,16 @@ import sop.operation.ChangeKeyPassword
|
|||
import sop.operation.Dearmor
|
||||
import sop.operation.Decrypt
|
||||
import sop.operation.DetachedSign
|
||||
import sop.operation.DetachedVerify
|
||||
import sop.operation.Encrypt
|
||||
import sop.operation.ExtractCert
|
||||
import sop.operation.GenerateKey
|
||||
import sop.operation.InlineDetach
|
||||
import sop.operation.InlineSign
|
||||
import sop.operation.InlineVerify
|
||||
import sop.operation.ListProfiles
|
||||
import sop.operation.RevokeKey
|
||||
import sop.operation.Version
|
||||
|
||||
/**
|
||||
* Stateless OpenPGP Interface. This class provides a stateless interface to various OpenPGP related
|
||||
|
@ -23,7 +26,10 @@ import sop.operation.RevokeKey
|
|||
* intended for reuse. If you for example need to generate multiple keys, make a dedicated call to
|
||||
* [generateKey] once per key generation.
|
||||
*/
|
||||
interface SOP : SOPV {
|
||||
interface SOP {
|
||||
|
||||
/** Get information about the implementations name and version. */
|
||||
fun version(): Version
|
||||
|
||||
/** Generate a secret key. */
|
||||
fun generateKey(): GenerateKey
|
||||
|
@ -47,6 +53,24 @@ interface SOP : SOPV {
|
|||
*/
|
||||
fun inlineSign(): InlineSign
|
||||
|
||||
/**
|
||||
* Verify detached signatures. If you need to verify an inline-signed message, use
|
||||
* [inlineVerify] instead.
|
||||
*/
|
||||
fun verify(): DetachedVerify = detachedVerify()
|
||||
|
||||
/**
|
||||
* Verify detached signatures. If you need to verify an inline-signed message, use
|
||||
* [inlineVerify] instead.
|
||||
*/
|
||||
fun detachedVerify(): DetachedVerify
|
||||
|
||||
/**
|
||||
* Verify signatures of an inline-signed message. If you need to verify detached signatures over
|
||||
* a message, use [detachedVerify] instead.
|
||||
*/
|
||||
fun inlineVerify(): InlineVerify
|
||||
|
||||
/** Detach signatures from an inline signed message. */
|
||||
fun inlineDetach(): InlineDetach
|
||||
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package sop
|
||||
|
||||
import sop.operation.DetachedVerify
|
||||
import sop.operation.InlineVerify
|
||||
import sop.operation.Version
|
||||
|
||||
/** Subset of [SOP] implementing only OpenPGP signature verification. */
|
||||
interface SOPV {
|
||||
|
||||
/** Get information about the implementations name and version. */
|
||||
fun version(): Version
|
||||
|
||||
/**
|
||||
* Verify detached signatures. If you need to verify an inline-signed message, use
|
||||
* [inlineVerify] instead.
|
||||
*/
|
||||
fun verify(): DetachedVerify = detachedVerify()
|
||||
|
||||
/**
|
||||
* Verify detached signatures. If you need to verify an inline-signed message, use
|
||||
* [inlineVerify] instead.
|
||||
*/
|
||||
fun detachedVerify(): DetachedVerify
|
||||
|
||||
/**
|
||||
* Verify signatures of an inline-signed message. If you need to verify detached signatures over
|
||||
* a message, use [detachedVerify] instead.
|
||||
*/
|
||||
fun inlineVerify(): InlineVerify
|
||||
}
|
14
sop-java/src/main/kotlin/sop/enums/ArmorLabel.kt
Normal file
14
sop-java/src/main/kotlin/sop/enums/ArmorLabel.kt
Normal file
|
@ -0,0 +1,14 @@
|
|||
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package sop.enums
|
||||
|
||||
@Deprecated("Use of armor labels is deprecated.")
|
||||
enum class ArmorLabel {
|
||||
auto,
|
||||
sig,
|
||||
key,
|
||||
cert,
|
||||
message
|
||||
}
|
|
@ -305,36 +305,4 @@ abstract class SOPGPException : RuntimeException {
|
|||
const val EXIT_CODE = 89
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The sop implementation supports some form of hardware-backed secret keys, but could not
|
||||
* identify the hardware device.
|
||||
*/
|
||||
class NoHardwareKeyFound : SOPGPException {
|
||||
constructor() : super()
|
||||
|
||||
constructor(errorMsg: String) : super(errorMsg)
|
||||
|
||||
override fun getExitCode(): Int = EXIT_CODE
|
||||
|
||||
companion object {
|
||||
const val EXIT_CODE = 97
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The sop implementation tried to use a hardware-backed secret key, but the cryptographic
|
||||
* hardware refused the operation for some reason other than a bad PIN or password.
|
||||
*/
|
||||
class HardwareKeyFailure : SOPGPException {
|
||||
constructor() : super()
|
||||
|
||||
constructor(errorMsg: String) : super(errorMsg)
|
||||
|
||||
override fun getExitCode(): Int = EXIT_CODE
|
||||
|
||||
companion object {
|
||||
const val EXIT_CODE = 101
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,22 @@ package sop.operation
|
|||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import sop.Ready
|
||||
import sop.enums.ArmorLabel
|
||||
import sop.exception.SOPGPException.BadData
|
||||
import sop.exception.SOPGPException.UnsupportedOption
|
||||
|
||||
interface Armor {
|
||||
|
||||
/**
|
||||
* Overrides automatic detection of label.
|
||||
*
|
||||
* @param label armor label
|
||||
* @return builder instance
|
||||
*/
|
||||
@Deprecated("Use of armor labels is deprecated and will be removed in a future release.")
|
||||
@Throws(UnsupportedOption::class)
|
||||
fun label(label: ArmorLabel): Armor
|
||||
|
||||
/**
|
||||
* Armor the provided data.
|
||||
*
|
||||
|
|
|
@ -4,9 +4,6 @@
|
|||
|
||||
package sop.operation
|
||||
|
||||
import kotlin.jvm.Throws
|
||||
import sop.exception.SOPGPException
|
||||
|
||||
interface Version {
|
||||
|
||||
/**
|
||||
|
@ -100,11 +97,4 @@ interface Version {
|
|||
* @return remarks or null
|
||||
*/
|
||||
fun getSopSpecImplementationRemarks(): String?
|
||||
|
||||
/**
|
||||
* Return the single-line SEMVER version of the sopv interface subset it provides complete
|
||||
* coverage of. If the implementation does not provide complete coverage for any sopv interface,
|
||||
* this method throws an [SOPGPException.UnsupportedOption] instead.
|
||||
*/
|
||||
@Throws(SOPGPException.UnsupportedOption::class) fun getSopVVersion(): String
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ import java.io.OutputStream
|
|||
* class is useful if we need to provide an [OutputStream] at one point in time when the final
|
||||
* target output stream is not yet known.
|
||||
*/
|
||||
@Deprecated("Marked for removal.")
|
||||
class ProxyOutputStream : OutputStream() {
|
||||
private val buffer = ByteArrayOutputStream()
|
||||
private var swapped: OutputStream? = null
|
||||
|
|
|
@ -1,235 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package sop.testsuite.assertions;
|
||||
|
||||
import sop.exception.SOPGPException;
|
||||
|
||||
import java.util.function.IntSupplier;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
/**
|
||||
* DSL for testing the return values of SOP method calls.
|
||||
*/
|
||||
public class SopExecutionAssertions {
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns 0.
|
||||
*
|
||||
* @param function function to execute
|
||||
*/
|
||||
public static void assertSuccess(IntSupplier function) {
|
||||
assertEquals(0, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns a generic error with error code 1.
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertGenericError(IntSupplier function) {
|
||||
assertEquals(1, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns a non-zero error code.
|
||||
*
|
||||
* @param function function to execute
|
||||
*/
|
||||
public static void assertAnyError(IntSupplier function) {
|
||||
assertNotEquals(0, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 3
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.NoSignature}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertNoSignature(IntSupplier function) {
|
||||
assertEquals(SOPGPException.NoSignature.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 13
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.UnsupportedAsymmetricAlgo}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertUnsupportedAsymmetricAlgo(IntSupplier function) {
|
||||
assertEquals(SOPGPException.UnsupportedAsymmetricAlgo.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 17
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.CertCannotEncrypt}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertCertCannotEncrypt(IntSupplier function) {
|
||||
assertEquals(SOPGPException.CertCannotEncrypt.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 19
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.MissingArg}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertMissingArg(IntSupplier function) {
|
||||
assertEquals(SOPGPException.MissingArg.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 23
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.IncompleteVerification}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertIncompleteVerification(IntSupplier function) {
|
||||
assertEquals(SOPGPException.IncompleteVerification.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 29
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.CannotDecrypt}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertCannotDecrypt(IntSupplier function) {
|
||||
assertEquals(SOPGPException.CannotDecrypt.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 31
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.PasswordNotHumanReadable}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertPasswordNotHumanReadable(IntSupplier function) {
|
||||
assertEquals(SOPGPException.PasswordNotHumanReadable.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 37
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.UnsupportedOption}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertUnsupportedOption(IntSupplier function) {
|
||||
assertEquals(SOPGPException.UnsupportedOption.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 41
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.BadData}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertBadData(IntSupplier function) {
|
||||
assertEquals(SOPGPException.BadData.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 53
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.ExpectedText}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertExpectedText(IntSupplier function) {
|
||||
assertEquals(SOPGPException.ExpectedText.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 59
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.OutputExists}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertOutputExists(IntSupplier function) {
|
||||
assertEquals(SOPGPException.OutputExists.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 61
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.MissingInput}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertMissingInput(IntSupplier function) {
|
||||
assertEquals(SOPGPException.MissingInput.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 67
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.KeyIsProtected}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertKeyIsProtected(IntSupplier function) {
|
||||
assertEquals(SOPGPException.KeyIsProtected.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 69
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.UnsupportedSubcommand}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertUnsupportedSubcommand(IntSupplier function) {
|
||||
assertEquals(SOPGPException.UnsupportedSubcommand.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 71
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.UnsupportedSpecialPrefix}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertUnsupportedSpecialPrefix(IntSupplier function) {
|
||||
assertEquals(SOPGPException.UnsupportedSpecialPrefix.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 73
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.AmbiguousInput}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertAmbiguousInput(IntSupplier function) {
|
||||
assertEquals(SOPGPException.AmbiguousInput.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 79
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.KeyCannotSign}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertKeyCannotSign(IntSupplier function) {
|
||||
assertEquals(SOPGPException.KeyCannotSign.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 83
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.IncompatibleOptions}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertIncompatibleOptions(IntSupplier function) {
|
||||
assertEquals(SOPGPException.IncompatibleOptions.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the execution of the given function returns error code 89
|
||||
* (which corresponds to {@link sop.exception.SOPGPException.UnsupportedProfile}).
|
||||
*
|
||||
* @param function function to execute.
|
||||
*/
|
||||
public static void assertUnsupportedProfile(IntSupplier function) {
|
||||
assertEquals(SOPGPException.UnsupportedProfile.EXIT_CODE, function.getAsInt());
|
||||
}
|
||||
}
|
|
@ -327,15 +327,4 @@ public class EncryptDecryptTest extends AbstractSOPTest {
|
|||
.toByteArrayAndResult()
|
||||
.getBytes());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideInstances")
|
||||
public void passingSecretKeysForPublicKeysFails(SOP sop) {
|
||||
assertThrows(SOPGPException.BadData.class, () ->
|
||||
sop.encrypt()
|
||||
.withCert(TestData.ALICE_KEY.getBytes(StandardCharsets.UTF_8))
|
||||
.plaintext(TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8))
|
||||
.toByteArrayAndResult()
|
||||
.getBytes());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,15 +8,14 @@ import org.junit.jupiter.api.condition.EnabledIf;
|
|||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.opentest4j.TestAbortedException;
|
||||
import sop.SOP;
|
||||
import sop.exception.SOPGPException;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
|
||||
@EnabledIf("sop.testsuite.operation.AbstractSOPTest#hasBackends")
|
||||
public class VersionTest extends AbstractSOPTest {
|
||||
|
@ -60,7 +59,7 @@ public class VersionTest extends AbstractSOPTest {
|
|||
try {
|
||||
sop.version().getSopSpecVersion();
|
||||
} catch (RuntimeException e) {
|
||||
throw new TestAbortedException("SOP backend does not support 'version --sop-spec' yet.");
|
||||
assumeTrue(false); // SOP backend does not support this operation yet
|
||||
}
|
||||
|
||||
String sopSpec = sop.version().getSopSpecVersion();
|
||||
|
@ -73,17 +72,4 @@ public class VersionTest extends AbstractSOPTest {
|
|||
int sopRevision = sop.version().getSopSpecRevisionNumber();
|
||||
assertTrue(sop.version().getSopSpecRevisionName().endsWith("" + sopRevision));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideInstances")
|
||||
public void sopVVersionTest(SOP sop) {
|
||||
try {
|
||||
sop.version().getSopVVersion();
|
||||
} catch (SOPGPException.UnsupportedOption e) {
|
||||
throw new TestAbortedException(
|
||||
"Implementation does (gracefully) not provide coverage for any sopv interface version.");
|
||||
} catch (RuntimeException e) {
|
||||
throw new TestAbortedException("Implementation does not provide coverage for any sopv interface version.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
|
||||
allprojects {
|
||||
ext {
|
||||
shortVersion = '10.0.1'
|
||||
isSnapshot = true
|
||||
shortVersion = '8.0.0'
|
||||
isSnapshot = false
|
||||
minAndroidSdk = 10
|
||||
javaSourceCompatibility = 1.8
|
||||
gsonVersion = '2.10.1'
|
||||
jsrVersion = '3.0.2'
|
||||
junitVersion = '5.8.2'
|
||||
junitSysExitVersion = '1.1.2'
|
||||
logbackVersion = '1.2.13'
|
||||
logbackVersion = '1.2.11'
|
||||
mockitoVersion = '4.5.1'
|
||||
picocliVersion = '4.6.3'
|
||||
slf4jVersion = '1.7.36'
|
||||
|
|
Loading…
Reference in a new issue