mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-29 15:52:08 +01:00
Wip: Adopt changes from the SOP specification version 2
This commit is contained in:
parent
829068d5a8
commit
788c82531e
17 changed files with 328 additions and 217 deletions
|
@ -101,7 +101,6 @@ public class EncryptDecryptTest {
|
||||||
msgAscOut.close();
|
msgAscOut.close();
|
||||||
|
|
||||||
File verifyFile = new File(tempDir, "verify.txt");
|
File verifyFile = new File(tempDir, "verify.txt");
|
||||||
assertTrue(verifyFile.createNewFile());
|
|
||||||
|
|
||||||
FileInputStream msgAscIn = new FileInputStream(msgAscFile);
|
FileInputStream msgAscIn = new FileInputStream(msgAscFile);
|
||||||
System.setIn(msgAscIn);
|
System.setIn(msgAscIn);
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class ArmorImpl implements Armor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Armor label(ArmorLabel label) throws SOPGPException.UnsupportedOption {
|
public Armor label(ArmorLabel label) throws SOPGPException.UnsupportedOption {
|
||||||
throw new SOPGPException.UnsupportedOption();
|
throw new SOPGPException.UnsupportedOption("Setting custom Armor labels not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class DecryptImpl implements Decrypt {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DecryptImpl withSessionKey(SessionKey sessionKey) throws SOPGPException.UnsupportedOption {
|
public DecryptImpl withSessionKey(SessionKey sessionKey) throws SOPGPException.UnsupportedOption {
|
||||||
throw new SOPGPException.UnsupportedOption();
|
throw new SOPGPException.UnsupportedOption("Setting custom session key not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class GenerateKeyImpl implements GenerateKey {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException e) {
|
} catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException e) {
|
||||||
throw new SOPGPException.UnsupportedAsymmetricAlgo(e);
|
throw new SOPGPException.UnsupportedAsymmetricAlgo("Unsupported asymmetric algorithm.", e);
|
||||||
} catch (PGPException e) {
|
} catch (PGPException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package sop.cli.picocli;
|
||||||
|
|
||||||
|
import picocli.CommandLine;
|
||||||
|
import sop.exception.SOPGPException;
|
||||||
|
|
||||||
|
public class SOPExceptionExitCodeMapper implements CommandLine.IExitCodeExceptionMapper {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getExitCode(Throwable exception) {
|
||||||
|
if (exception instanceof SOPGPException) {
|
||||||
|
return ((SOPGPException) exception).getExitCode();
|
||||||
|
}
|
||||||
|
if (exception instanceof CommandLine.UnmatchedArgumentException) {
|
||||||
|
CommandLine.UnmatchedArgumentException ex = (CommandLine.UnmatchedArgumentException) exception;
|
||||||
|
// Unmatched option of subcommand (eg. `generate-key -k`)
|
||||||
|
if (ex.isUnknownOption()) {
|
||||||
|
return SOPGPException.UnsupportedOption.EXIT_CODE;
|
||||||
|
}
|
||||||
|
// Unmatched subcommand
|
||||||
|
return SOPGPException.UnsupportedSubcommand.EXIT_CODE;
|
||||||
|
}
|
||||||
|
// Invalid option (eg. `--label Invalid`)
|
||||||
|
if (exception instanceof CommandLine.ParameterException) {
|
||||||
|
return SOPGPException.UnsupportedOption.EXIT_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Others, like IOException etc.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package sop.cli.picocli;
|
||||||
|
|
||||||
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
public class SOPExecutionExceptionHandler implements CommandLine.IExecutionExceptionHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int handleExecutionException(Exception ex, CommandLine commandLine, CommandLine.ParseResult parseResult) throws Exception {
|
||||||
|
int exitCode = commandLine.getExitCodeExceptionMapper() != null ?
|
||||||
|
commandLine.getExitCodeExceptionMapper().getExitCode(ex) :
|
||||||
|
commandLine.getCommandSpec().exitCodeOnExecutionException();
|
||||||
|
CommandLine.Help.ColorScheme colorScheme = commandLine.getColorScheme();
|
||||||
|
// CHECKSTYLE:OFF
|
||||||
|
if (ex.getMessage() != null) {
|
||||||
|
commandLine.getErr().println(colorScheme.errorText(ex.getMessage()));
|
||||||
|
}
|
||||||
|
ex.printStackTrace(commandLine.getErr());
|
||||||
|
// CHECKSTYLE:ON
|
||||||
|
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -58,6 +58,8 @@ public class SopCLI {
|
||||||
public static int execute(String[] args) {
|
public static int execute(String[] args) {
|
||||||
return new CommandLine(SopCLI.class)
|
return new CommandLine(SopCLI.class)
|
||||||
.setCommandName(EXECUTABLE_NAME)
|
.setCommandName(EXECUTABLE_NAME)
|
||||||
|
.setExecutionExceptionHandler(new SOPExecutionExceptionHandler())
|
||||||
|
.setExitCodeExceptionMapper(new SOPExceptionExitCodeMapper())
|
||||||
.setCaseInsensitiveEnumValuesAllowed(true)
|
.setCaseInsensitiveEnumValuesAllowed(true)
|
||||||
.execute(args);
|
.execute(args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import sop.ReadyWithResult;
|
||||||
import sop.SessionKey;
|
import sop.SessionKey;
|
||||||
import sop.Verification;
|
import sop.Verification;
|
||||||
import sop.cli.picocli.DateParser;
|
import sop.cli.picocli.DateParser;
|
||||||
import sop.cli.picocli.Print;
|
|
||||||
import sop.cli.picocli.SopCLI;
|
import sop.cli.picocli.SopCLI;
|
||||||
import sop.exception.SOPGPException;
|
import sop.exception.SOPGPException;
|
||||||
import sop.operation.Decrypt;
|
import sop.operation.Decrypt;
|
||||||
|
@ -93,9 +92,13 @@ public class DecryptCmd implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
unlinkExistingVerifyOut(verifyOut);
|
throwIfVerifyOutExists(verifyOut);
|
||||||
|
|
||||||
Decrypt decrypt = SopCLI.getSop().decrypt();
|
Decrypt decrypt = SopCLI.getSop().decrypt();
|
||||||
|
if (decrypt == null) {
|
||||||
|
throw new SOPGPException.UnsupportedSubcommand("Subcommand 'decrypt' not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
setNotAfter(notAfter, decrypt);
|
setNotAfter(notAfter, decrypt);
|
||||||
setNotBefore(notBefore, decrypt);
|
setNotBefore(notBefore, decrypt);
|
||||||
setWithPasswords(withPassword, decrypt);
|
setWithPasswords(withPassword, decrypt);
|
||||||
|
@ -104,31 +107,22 @@ public class DecryptCmd implements Runnable {
|
||||||
setDecryptWith(keys, decrypt);
|
setDecryptWith(keys, decrypt);
|
||||||
|
|
||||||
if (verifyOut != null && certs.isEmpty()) {
|
if (verifyOut != null && certs.isEmpty()) {
|
||||||
Print.errln("--verify-out is requested, but no --verify-with was provided.");
|
throw new SOPGPException.IncompleteVerification("--verify-out is requested, but no --verify-with was provided.");
|
||||||
System.exit(23);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ReadyWithResult<DecryptionResult> ready = decrypt.ciphertext(System.in);
|
ReadyWithResult<DecryptionResult> ready = decrypt.ciphertext(System.in);
|
||||||
DecryptionResult result = ready.writeTo(System.out);
|
DecryptionResult result = ready.writeTo(System.out);
|
||||||
if (sessionKeyOut != null) {
|
writeSessionKeyOut(result);
|
||||||
if (sessionKeyOut.exists()) {
|
writeVerifyOut(result);
|
||||||
Print.errln("File " + sessionKeyOut.getAbsolutePath() + " already exists.");
|
} catch (SOPGPException.BadData badData) {
|
||||||
Print.trace(new SOPGPException.OutputExists());
|
throw new SOPGPException.BadData("No valid OpenPGP message found on Standard Input.", badData);
|
||||||
System.exit(1);
|
} catch (IOException ioException) {
|
||||||
|
throw new RuntimeException(ioException);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try (FileOutputStream outputStream = new FileOutputStream(sessionKeyOut)) {
|
private void writeVerifyOut(DecryptionResult result) throws IOException {
|
||||||
if (!result.getSessionKey().isPresent()) {
|
|
||||||
Print.errln("Session key not extracted. Possibly the feature is not supported.");
|
|
||||||
System.exit(SOPGPException.UnsupportedOption.EXIT_CODE);
|
|
||||||
} else {
|
|
||||||
SessionKey sessionKey = result.getSessionKey().get();
|
|
||||||
outputStream.write(sessionKey.getAlgorithm());
|
|
||||||
outputStream.write(sessionKey.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (verifyOut != null) {
|
if (verifyOut != null) {
|
||||||
if (!verifyOut.createNewFile()) {
|
if (!verifyOut.createNewFile()) {
|
||||||
throw new IOException("Cannot create file " + verifyOut.getAbsolutePath());
|
throw new IOException("Cannot create file " + verifyOut.getAbsolutePath());
|
||||||
|
@ -143,26 +137,33 @@ public class DecryptCmd implements Runnable {
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SOPGPException.BadData badData) {
|
}
|
||||||
Print.errln("No valid OpenPGP message found on Standard Input.");
|
|
||||||
Print.trace(badData);
|
private void writeSessionKeyOut(DecryptionResult result) throws IOException {
|
||||||
System.exit(badData.getExitCode());
|
if (sessionKeyOut != null) {
|
||||||
} catch (SOPGPException.MissingArg missingArg) {
|
if (sessionKeyOut.exists()) {
|
||||||
Print.errln("Missing arguments.");
|
throw new SOPGPException.OutputExists("Target " + sessionKeyOut.getAbsolutePath() + " of option --session-key-out already exists.");
|
||||||
Print.trace(missingArg);
|
}
|
||||||
System.exit(missingArg.getExitCode());
|
|
||||||
} catch (IOException e) {
|
try (FileOutputStream outputStream = new FileOutputStream(sessionKeyOut)) {
|
||||||
Print.errln("IO Error.");
|
if (!result.getSessionKey().isPresent()) {
|
||||||
Print.trace(e);
|
throw new SOPGPException.UnsupportedOption("Session key not extracted. Possibly the feature --session-key-out is not supported.");
|
||||||
System.exit(1);
|
} else {
|
||||||
} catch (SOPGPException.NoSignature noSignature) {
|
SessionKey sessionKey = result.getSessionKey().get();
|
||||||
Print.errln("No verifiable signature found.");
|
outputStream.write(sessionKey.getAlgorithm());
|
||||||
Print.trace(noSignature);
|
outputStream.write(sessionKey.getKey());
|
||||||
System.exit(noSignature.getExitCode());
|
}
|
||||||
} catch (SOPGPException.CannotDecrypt cannotDecrypt) {
|
}
|
||||||
Print.errln("Cannot decrypt.");
|
}
|
||||||
Print.trace(cannotDecrypt);
|
}
|
||||||
System.exit(cannotDecrypt.getExitCode());
|
|
||||||
|
private void throwIfVerifyOutExists(File verifyOut) throws SOPGPException.OutputExists {
|
||||||
|
if (verifyOut == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verifyOut.exists()) {
|
||||||
|
throw new SOPGPException.OutputExists("Target " + verifyOut.getAbsolutePath() + " of option --verify-out already exists.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,25 +172,13 @@ public class DecryptCmd implements Runnable {
|
||||||
try (FileInputStream keyIn = new FileInputStream(key)) {
|
try (FileInputStream keyIn = new FileInputStream(key)) {
|
||||||
decrypt.withKey(keyIn);
|
decrypt.withKey(keyIn);
|
||||||
} catch (SOPGPException.KeyIsProtected keyIsProtected) {
|
} catch (SOPGPException.KeyIsProtected keyIsProtected) {
|
||||||
Print.errln("Key in file " + key.getAbsolutePath() + " is password protected.");
|
throw new SOPGPException.KeyIsProtected("Key in file " + key.getAbsolutePath() + " is password protected.", keyIsProtected);
|
||||||
Print.trace(keyIsProtected);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (SOPGPException.UnsupportedAsymmetricAlgo unsupportedAsymmetricAlgo) {
|
|
||||||
Print.errln("Key uses unsupported asymmetric algorithm.");
|
|
||||||
Print.trace(unsupportedAsymmetricAlgo);
|
|
||||||
System.exit(unsupportedAsymmetricAlgo.getExitCode());
|
|
||||||
} catch (SOPGPException.BadData badData) {
|
} catch (SOPGPException.BadData badData) {
|
||||||
Print.errln("File " + key.getAbsolutePath() + " does not contain a private key.");
|
throw new SOPGPException.BadData("File " + key.getAbsolutePath() + " does not contain a private key.", badData);
|
||||||
Print.trace(badData);
|
|
||||||
System.exit(badData.getExitCode());
|
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Print.errln("File " + key.getAbsolutePath() + " does not exist.");
|
throw new SOPGPException.MissingInput("File " + key.getAbsolutePath() + " does not exist.", e);
|
||||||
Print.trace(e);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Print.errln("IO Error.");
|
throw new RuntimeException(e);
|
||||||
Print.trace(e);
|
|
||||||
System.exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,30 +188,11 @@ public class DecryptCmd implements Runnable {
|
||||||
try (FileInputStream certIn = new FileInputStream(cert)) {
|
try (FileInputStream certIn = new FileInputStream(cert)) {
|
||||||
decrypt.verifyWithCert(certIn);
|
decrypt.verifyWithCert(certIn);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Print.errln("File " + cert.getAbsolutePath() + " does not exist.");
|
throw new SOPGPException.MissingInput("File " + cert.getAbsolutePath() + " does not exist.", e);
|
||||||
Print.trace(e);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Print.errln("IO Error.");
|
|
||||||
Print.trace(e);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (SOPGPException.BadData badData) {
|
} catch (SOPGPException.BadData badData) {
|
||||||
Print.errln("File " + cert.getAbsolutePath() + " does not contain a valid certificate.");
|
throw new SOPGPException.BadData("File " + cert.getAbsolutePath() + " does not contain a valid certificate.", badData);
|
||||||
Print.trace(badData);
|
} catch (IOException ioException) {
|
||||||
System.exit(badData.getExitCode());
|
throw new RuntimeException(ioException);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unlinkExistingVerifyOut(File verifyOut) {
|
|
||||||
if (verifyOut == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verifyOut.exists()) {
|
|
||||||
if (!verifyOut.delete()) {
|
|
||||||
Print.errln("Cannot delete existing verification file" + verifyOut.getAbsolutePath());
|
|
||||||
System.exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,9 +201,7 @@ public class DecryptCmd implements Runnable {
|
||||||
Pattern sessionKeyPattern = Pattern.compile("^\\d+:[0-9A-F]+$");
|
Pattern sessionKeyPattern = Pattern.compile("^\\d+:[0-9A-F]+$");
|
||||||
for (String sessionKey : withSessionKey) {
|
for (String sessionKey : withSessionKey) {
|
||||||
if (!sessionKeyPattern.matcher(sessionKey).matches()) {
|
if (!sessionKeyPattern.matcher(sessionKey).matches()) {
|
||||||
Print.errln("Invalid session key format.");
|
throw new IllegalArgumentException("Session keys are expected in the format 'ALGONUM:HEXKEY'.");
|
||||||
Print.errln("Session keys are expected in the format 'ALGONUM:HEXKEY'");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
}
|
||||||
String[] split = sessionKey.split(":");
|
String[] split = sessionKey.split(":");
|
||||||
byte algorithm = (byte) Integer.parseInt(split[0]);
|
byte algorithm = (byte) Integer.parseInt(split[0]);
|
||||||
|
@ -242,10 +210,7 @@ public class DecryptCmd implements Runnable {
|
||||||
try {
|
try {
|
||||||
decrypt.withSessionKey(new SessionKey(algorithm, key));
|
decrypt.withSessionKey(new SessionKey(algorithm, key));
|
||||||
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
||||||
Print.errln("Unsupported option '--with-session-key'.");
|
throw new SOPGPException.UnsupportedOption("Unsupported option '--with-session-key'.", unsupportedOption);
|
||||||
Print.trace(unsupportedOption);
|
|
||||||
System.exit(unsupportedOption.getExitCode());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,14 +219,8 @@ public class DecryptCmd implements Runnable {
|
||||||
for (String password : withPassword) {
|
for (String password : withPassword) {
|
||||||
try {
|
try {
|
||||||
decrypt.withPassword(password);
|
decrypt.withPassword(password);
|
||||||
} catch (SOPGPException.PasswordNotHumanReadable passwordNotHumanReadable) {
|
|
||||||
Print.errln("Password not human readable.");
|
|
||||||
Print.trace(passwordNotHumanReadable);
|
|
||||||
System.exit(passwordNotHumanReadable.getExitCode());
|
|
||||||
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
||||||
Print.errln("Unsupported option '--with-password'.");
|
throw new SOPGPException.UnsupportedOption("Unsupported option '--with-password'.", unsupportedOption);
|
||||||
Print.trace(unsupportedOption);
|
|
||||||
System.exit(unsupportedOption.getExitCode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,9 +230,7 @@ public class DecryptCmd implements Runnable {
|
||||||
try {
|
try {
|
||||||
decrypt.verifyNotAfter(notAfterDate);
|
decrypt.verifyNotAfter(notAfterDate);
|
||||||
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
||||||
Print.errln("Option '--not-after' not supported.");
|
throw new SOPGPException.UnsupportedOption("Option '--not-after' not supported.", unsupportedOption);
|
||||||
Print.trace(unsupportedOption);
|
|
||||||
System.exit(unsupportedOption.getExitCode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,9 +239,7 @@ public class DecryptCmd implements Runnable {
|
||||||
try {
|
try {
|
||||||
decrypt.verifyNotBefore(notBeforeDate);
|
decrypt.verifyNotBefore(notBeforeDate);
|
||||||
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
||||||
Print.errln("Option '--not-before' not supported.");
|
throw new SOPGPException.UnsupportedOption("Option '--not-before' not supported.", unsupportedOption);
|
||||||
Print.trace(unsupportedOption);
|
|
||||||
System.exit(unsupportedOption.getExitCode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.util.List;
|
||||||
|
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
import sop.Ready;
|
import sop.Ready;
|
||||||
import sop.cli.picocli.Print;
|
|
||||||
import sop.cli.picocli.SopCLI;
|
import sop.cli.picocli.SopCLI;
|
||||||
import sop.enums.EncryptAs;
|
import sop.enums.EncryptAs;
|
||||||
import sop.exception.SOPGPException;
|
import sop.exception.SOPGPException;
|
||||||
|
@ -67,28 +66,19 @@ public class EncryptCmd implements Runnable {
|
||||||
try {
|
try {
|
||||||
encrypt.mode(type);
|
encrypt.mode(type);
|
||||||
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
||||||
Print.errln("Unsupported option '--as'.");
|
throw new SOPGPException.UnsupportedOption("Unsupported option '--as'.", unsupportedOption);
|
||||||
Print.trace(unsupportedOption);
|
|
||||||
System.exit(unsupportedOption.getExitCode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withPassword.isEmpty() && certs.isEmpty()) {
|
if (withPassword.isEmpty() && certs.isEmpty()) {
|
||||||
Print.errln("At least one password or cert file required for encryption.");
|
throw new SOPGPException.MissingArg("At least one password or cert file required for encryption.");
|
||||||
System.exit(19);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String password : withPassword) {
|
for (String password : withPassword) {
|
||||||
try {
|
try {
|
||||||
encrypt.withPassword(password);
|
encrypt.withPassword(password);
|
||||||
} catch (SOPGPException.PasswordNotHumanReadable passwordNotHumanReadable) {
|
|
||||||
Print.errln("Password is not human-readable.");
|
|
||||||
Print.trace(passwordNotHumanReadable);
|
|
||||||
System.exit(passwordNotHumanReadable.getExitCode());
|
|
||||||
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
} catch (SOPGPException.UnsupportedOption unsupportedOption) {
|
||||||
Print.errln("Unsupported option '--with-password'.");
|
throw new SOPGPException.UnsupportedOption("Unsupported option '--with-password'.", unsupportedOption);
|
||||||
Print.trace(unsupportedOption);
|
|
||||||
System.exit(unsupportedOption.getExitCode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,29 +86,17 @@ public class EncryptCmd implements Runnable {
|
||||||
try (FileInputStream keyIn = new FileInputStream(keyFile)) {
|
try (FileInputStream keyIn = new FileInputStream(keyFile)) {
|
||||||
encrypt.signWith(keyIn);
|
encrypt.signWith(keyIn);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Print.errln("Key file " + keyFile.getAbsolutePath() + " not found.");
|
throw new SOPGPException.MissingInput("Key file " + keyFile.getAbsolutePath() + " not found.", e);
|
||||||
Print.trace(e);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Print.errln("IO Error.");
|
throw new RuntimeException(e);
|
||||||
Print.trace(e);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (SOPGPException.KeyIsProtected keyIsProtected) {
|
} catch (SOPGPException.KeyIsProtected keyIsProtected) {
|
||||||
Print.errln("Key from " + keyFile.getAbsolutePath() + " is password protected.");
|
throw new SOPGPException.KeyIsProtected("Key from " + keyFile.getAbsolutePath() + " is password protected.", keyIsProtected);
|
||||||
Print.trace(keyIsProtected);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (SOPGPException.UnsupportedAsymmetricAlgo unsupportedAsymmetricAlgo) {
|
} catch (SOPGPException.UnsupportedAsymmetricAlgo unsupportedAsymmetricAlgo) {
|
||||||
Print.errln("Key from " + keyFile.getAbsolutePath() + " has unsupported asymmetric algorithm.");
|
throw new SOPGPException.UnsupportedAsymmetricAlgo("Key from " + keyFile.getAbsolutePath() + " has unsupported asymmetric algorithm.", unsupportedAsymmetricAlgo);
|
||||||
Print.trace(unsupportedAsymmetricAlgo);
|
|
||||||
System.exit(unsupportedAsymmetricAlgo.getExitCode());
|
|
||||||
} catch (SOPGPException.CertCannotSign certCannotSign) {
|
} catch (SOPGPException.CertCannotSign certCannotSign) {
|
||||||
Print.errln("Key from " + keyFile.getAbsolutePath() + " cannot sign.");
|
throw new RuntimeException("Key from " + keyFile.getAbsolutePath() + " cannot sign.", certCannotSign);
|
||||||
Print.trace(certCannotSign);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (SOPGPException.BadData badData) {
|
} catch (SOPGPException.BadData badData) {
|
||||||
Print.errln("Key file " + keyFile.getAbsolutePath() + " does not contain a valid OpenPGP private key.");
|
throw new SOPGPException.BadData("Key file " + keyFile.getAbsolutePath() + " does not contain a valid OpenPGP private key.", badData);
|
||||||
Print.trace(badData);
|
|
||||||
System.exit(badData.getExitCode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,25 +104,15 @@ public class EncryptCmd implements Runnable {
|
||||||
try (FileInputStream certIn = new FileInputStream(certFile)) {
|
try (FileInputStream certIn = new FileInputStream(certFile)) {
|
||||||
encrypt.withCert(certIn);
|
encrypt.withCert(certIn);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
Print.errln("Certificate file " + certFile.getAbsolutePath() + " not found.");
|
throw new SOPGPException.MissingInput("Certificate file " + certFile.getAbsolutePath() + " not found.", e);
|
||||||
Print.trace(e);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Print.errln("IO Error.");
|
throw new RuntimeException(e);
|
||||||
Print.trace(e);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (SOPGPException.UnsupportedAsymmetricAlgo unsupportedAsymmetricAlgo) {
|
} catch (SOPGPException.UnsupportedAsymmetricAlgo unsupportedAsymmetricAlgo) {
|
||||||
Print.errln("Certificate from " + certFile.getAbsolutePath() + " has unsupported asymmetric algorithm.");
|
throw new SOPGPException.UnsupportedAsymmetricAlgo("Certificate from " + certFile.getAbsolutePath() + " has unsupported asymmetric algorithm.", unsupportedAsymmetricAlgo);
|
||||||
Print.trace(unsupportedAsymmetricAlgo);
|
|
||||||
System.exit(unsupportedAsymmetricAlgo.getExitCode());
|
|
||||||
} catch (SOPGPException.CertCannotEncrypt certCannotEncrypt) {
|
} catch (SOPGPException.CertCannotEncrypt certCannotEncrypt) {
|
||||||
Print.errln("Certificate from " + certFile.getAbsolutePath() + " is not capable of encryption.");
|
throw new SOPGPException.CertCannotEncrypt("Certificate from " + certFile.getAbsolutePath() + " is not capable of encryption.", certCannotEncrypt);
|
||||||
Print.trace(certCannotEncrypt);
|
|
||||||
System.exit(certCannotEncrypt.getExitCode());
|
|
||||||
} catch (SOPGPException.BadData badData) {
|
} catch (SOPGPException.BadData badData) {
|
||||||
Print.errln("Certificate file " + certFile.getAbsolutePath() + " does not contain a valid OpenPGP certificate.");
|
throw new SOPGPException.BadData("Certificate file " + certFile.getAbsolutePath() + " does not contain a valid OpenPGP certificate.", badData);
|
||||||
Print.trace(badData);
|
|
||||||
System.exit(badData.getExitCode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,9 +124,7 @@ public class EncryptCmd implements Runnable {
|
||||||
Ready ready = encrypt.plaintext(System.in);
|
Ready ready = encrypt.plaintext(System.in);
|
||||||
ready.writeTo(System.out);
|
ready.writeTo(System.out);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Print.errln("IO Error.");
|
throw new RuntimeException(e);
|
||||||
Print.trace(e);
|
|
||||||
System.exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
||||||
|
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
import sop.Ready;
|
import sop.Ready;
|
||||||
import sop.cli.picocli.Print;
|
|
||||||
import sop.cli.picocli.SopCLI;
|
import sop.cli.picocli.SopCLI;
|
||||||
import sop.exception.SOPGPException;
|
import sop.exception.SOPGPException;
|
||||||
import sop.operation.ExtractCert;
|
import sop.operation.ExtractCert;
|
||||||
|
@ -45,13 +44,9 @@ public class ExtractCertCmd implements Runnable {
|
||||||
Ready ready = extractCert.key(System.in);
|
Ready ready = extractCert.key(System.in);
|
||||||
ready.writeTo(System.out);
|
ready.writeTo(System.out);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Print.errln("IO Error.");
|
throw new RuntimeException(e);
|
||||||
Print.trace(e);
|
|
||||||
System.exit(1);
|
|
||||||
} catch (SOPGPException.BadData badData) {
|
} catch (SOPGPException.BadData badData) {
|
||||||
Print.errln("Standard Input does not contain valid OpenPGP private key material.");
|
throw new SOPGPException.BadData("Standard Input does not contain valid OpenPGP private key material.", badData);
|
||||||
Print.trace(badData);
|
|
||||||
System.exit(badData.getExitCode());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class ArmorCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(37)
|
@ExpectSystemExitWithStatus(37)
|
||||||
public void ifLabelsUnsupportedExit37() throws SOPGPException.UnsupportedOption {
|
public void ifLabelsUnsupportedExit37() throws SOPGPException.UnsupportedOption {
|
||||||
when(armor.label(any())).thenThrow(new SOPGPException.UnsupportedOption());
|
when(armor.label(any())).thenThrow(new SOPGPException.UnsupportedOption("Custom Armor labels are not supported."));
|
||||||
|
|
||||||
SopCLI.main(new String[] {"armor", "--label", "Sig"});
|
SopCLI.main(new String[] {"armor", "--label", "Sig"});
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ public class ArmorCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(37)
|
@ExpectSystemExitWithStatus(37)
|
||||||
public void ifAllowNestedUnsupportedExit37() throws SOPGPException.UnsupportedOption {
|
public void ifAllowNestedUnsupportedExit37() throws SOPGPException.UnsupportedOption {
|
||||||
when(armor.allowNested()).thenThrow(new SOPGPException.UnsupportedOption());
|
when(armor.allowNested()).thenThrow(new SOPGPException.UnsupportedOption("Allowing nested Armor not supported."));
|
||||||
|
|
||||||
SopCLI.main(new String[] {"armor", "--allow-nested"});
|
SopCLI.main(new String[] {"armor", "--allow-nested"});
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import java.io.BufferedReader;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -115,7 +114,7 @@ public class DecryptCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(37)
|
@ExpectSystemExitWithStatus(37)
|
||||||
public void assertUnsupportedWithPasswordCausesExit37() throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
|
public void assertUnsupportedWithPasswordCausesExit37() throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
|
||||||
when(decrypt.withPassword(any())).thenThrow(new SOPGPException.UnsupportedOption());
|
when(decrypt.withPassword(any())).thenThrow(new SOPGPException.UnsupportedOption("Decrypting with password not supported."));
|
||||||
SopCLI.main(new String[] {"decrypt", "--with-password", "swordfish"});
|
SopCLI.main(new String[] {"decrypt", "--with-password", "swordfish"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,20 +167,20 @@ public class DecryptCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(37)
|
@ExpectSystemExitWithStatus(37)
|
||||||
public void assertUnsupportedNotAfterCausesExit37() throws SOPGPException.UnsupportedOption {
|
public void assertUnsupportedNotAfterCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||||
when(decrypt.verifyNotAfter(any())).thenThrow(new SOPGPException.UnsupportedOption());
|
when(decrypt.verifyNotAfter(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting upper signature date boundary not supported."));
|
||||||
SopCLI.main(new String[] {"decrypt", "--not-after", "now"});
|
SopCLI.main(new String[] {"decrypt", "--not-after", "now"});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(37)
|
@ExpectSystemExitWithStatus(37)
|
||||||
public void assertUnsupportedNotBeforeCausesExit37() throws SOPGPException.UnsupportedOption {
|
public void assertUnsupportedNotBeforeCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||||
when(decrypt.verifyNotBefore(any())).thenThrow(new SOPGPException.UnsupportedOption());
|
when(decrypt.verifyNotBefore(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting lower signature date boundary not supported."));
|
||||||
SopCLI.main(new String[] {"decrypt", "--not-before", "now"});
|
SopCLI.main(new String[] {"decrypt", "--not-before", "now"});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(1)
|
@ExpectSystemExitWithStatus(59)
|
||||||
public void assertExistingSessionKeyOutFileCausesExit1() throws IOException {
|
public void assertExistingSessionKeyOutFileCausesExit59() throws IOException {
|
||||||
File tempFile = File.createTempFile("existing-session-key-", ".tmp");
|
File tempFile = File.createTempFile("existing-session-key-", ".tmp");
|
||||||
tempFile.deleteOnExit();
|
tempFile.deleteOnExit();
|
||||||
SopCLI.main(new String[] {"decrypt", "--session-key-out", tempFile.getAbsolutePath()});
|
SopCLI.main(new String[] {"decrypt", "--session-key-out", tempFile.getAbsolutePath()});
|
||||||
|
@ -257,19 +256,28 @@ public class DecryptCmdTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(1)
|
@ExpectSystemExitWithStatus(61)
|
||||||
public void unexistentCertFileCausesExit1() {
|
public void unexistentCertFileCausesExit61() {
|
||||||
SopCLI.main(new String[] {"decrypt", "--verify-with", "invalid"});
|
SopCLI.main(new String[] {"decrypt", "--verify-with", "invalid"});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void existingVerifyOutFileIsUnlinkedBeforeVerification() throws IOException, SOPGPException.CannotDecrypt, SOPGPException.MissingArg, SOPGPException.BadData {
|
@ExpectSystemExitWithStatus(59)
|
||||||
|
public void existingVerifyOutCausesExit59() throws IOException {
|
||||||
File certFile = File.createTempFile("existing-verify-out-cert", ".asc");
|
File certFile = File.createTempFile("existing-verify-out-cert", ".asc");
|
||||||
File existingVerifyOut = File.createTempFile("existing-verify-out", ".tmp");
|
File existingVerifyOut = File.createTempFile("existing-verify-out", ".tmp");
|
||||||
byte[] data = "some data".getBytes(StandardCharsets.UTF_8);
|
|
||||||
try (FileOutputStream out = new FileOutputStream(existingVerifyOut)) {
|
SopCLI.main(new String[] {"decrypt", "--verify-out", existingVerifyOut.getAbsolutePath(), "--verify-with", certFile.getAbsolutePath()});
|
||||||
out.write(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void verifyOutIsProperlyWritten() throws IOException, SOPGPException.CannotDecrypt, SOPGPException.MissingArg, SOPGPException.BadData {
|
||||||
|
File certFile = File.createTempFile("verify-out-cert", ".asc");
|
||||||
|
File verifyOut = new File(certFile.getParent(), "verify-out.txt");
|
||||||
|
if (verifyOut.exists()) {
|
||||||
|
verifyOut.delete();
|
||||||
|
}
|
||||||
|
verifyOut.deleteOnExit();
|
||||||
Date date = UTCUtil.parseUTCDate("2021-07-11T20:58:23Z");
|
Date date = UTCUtil.parseUTCDate("2021-07-11T20:58:23Z");
|
||||||
when(decrypt.ciphertext(any())).thenReturn(new ReadyWithResult<DecryptionResult>() {
|
when(decrypt.ciphertext(any())).thenReturn(new ReadyWithResult<DecryptionResult>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -283,8 +291,8 @@ public class DecryptCmdTest {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
SopCLI.main(new String[] {"decrypt", "--verify-out", existingVerifyOut.getAbsolutePath(), "--verify-with", certFile.getAbsolutePath()});
|
SopCLI.main(new String[] {"decrypt", "--verify-out", verifyOut.getAbsolutePath(), "--verify-with", certFile.getAbsolutePath()});
|
||||||
try (BufferedReader reader = new BufferedReader(new FileReader(existingVerifyOut))) {
|
try (BufferedReader reader = new BufferedReader(new FileReader(verifyOut))) {
|
||||||
String line = reader.readLine();
|
String line = reader.readLine();
|
||||||
assertEquals("2021-07-11T20:58:23Z 1B66A707819A920925BC6777C3E0AFC0B2DFF862 C8CD564EBF8D7BBA90611D8D071773658BF6BF86", line);
|
assertEquals("2021-07-11T20:58:23Z 1B66A707819A920925BC6777C3E0AFC0B2DFF862 C8CD564EBF8D7BBA90611D8D071773658BF6BF86", line);
|
||||||
}
|
}
|
||||||
|
@ -317,14 +325,14 @@ public class DecryptCmdTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(1)
|
@ExpectSystemExitWithStatus(61)
|
||||||
public void assertKeyFileNotFoundCausesExit1() {
|
public void assertKeyFileNotFoundCausesExit61() {
|
||||||
SopCLI.main(new String[] {"decrypt", "nonexistent-key"});
|
SopCLI.main(new String[] {"decrypt", "nonexistent-key"});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(1)
|
@ExpectSystemExitWithStatus(67)
|
||||||
public void assertProtectedKeyCausesExit1() throws IOException, SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData {
|
public void assertProtectedKeyCausesExit67() throws IOException, SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData {
|
||||||
when(decrypt.withKey(any())).thenThrow(new SOPGPException.KeyIsProtected());
|
when(decrypt.withKey(any())).thenThrow(new SOPGPException.KeyIsProtected());
|
||||||
File tempKeyFile = File.createTempFile("key-", ".tmp");
|
File tempKeyFile = File.createTempFile("key-", ".tmp");
|
||||||
SopCLI.main(new String[] {"decrypt", tempKeyFile.getAbsolutePath()});
|
SopCLI.main(new String[] {"decrypt", tempKeyFile.getAbsolutePath()});
|
||||||
|
@ -333,7 +341,7 @@ public class DecryptCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(13)
|
@ExpectSystemExitWithStatus(13)
|
||||||
public void assertUnsupportedAlgorithmExceptionCausesExit13() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException {
|
public void assertUnsupportedAlgorithmExceptionCausesExit13() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException {
|
||||||
when(decrypt.withKey(any())).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo(new IOException()));
|
when(decrypt.withKey(any())).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo("Unsupported asymmetric algorithm.", new IOException()));
|
||||||
File tempKeyFile = File.createTempFile("key-", ".tmp");
|
File tempKeyFile = File.createTempFile("key-", ".tmp");
|
||||||
SopCLI.main(new String[] {"decrypt", tempKeyFile.getAbsolutePath()});
|
SopCLI.main(new String[] {"decrypt", tempKeyFile.getAbsolutePath()});
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class EncryptCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(37)
|
@ExpectSystemExitWithStatus(37)
|
||||||
public void as_unsupportedEncryptAsCausesExit37() throws SOPGPException.UnsupportedOption {
|
public void as_unsupportedEncryptAsCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||||
when(encrypt.mode(any())).thenThrow(new SOPGPException.UnsupportedOption());
|
when(encrypt.mode(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting encryption mode not supported."));
|
||||||
|
|
||||||
SopCLI.main(new String[] {"encrypt", "--as", "Binary"});
|
SopCLI.main(new String[] {"encrypt", "--as", "Binary"});
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public class EncryptCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(37)
|
@ExpectSystemExitWithStatus(37)
|
||||||
public void withPassword_unsupportedWithPasswordCausesExit37() throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
|
public void withPassword_unsupportedWithPasswordCausesExit37() throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
|
||||||
when(encrypt.withPassword(any())).thenThrow(new SOPGPException.UnsupportedOption());
|
when(encrypt.withPassword(any())).thenThrow(new SOPGPException.UnsupportedOption("Encrypting with password not supported."));
|
||||||
|
|
||||||
SopCLI.main(new String[] {"encrypt", "--with-password", "orange"});
|
SopCLI.main(new String[] {"encrypt", "--with-password", "orange"});
|
||||||
}
|
}
|
||||||
|
@ -110,14 +110,14 @@ public class EncryptCmdTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(1)
|
@ExpectSystemExitWithStatus(61)
|
||||||
public void signWith_nonExistentKeyFileCausesExit1() {
|
public void signWith_nonExistentKeyFileCausesExit61() {
|
||||||
SopCLI.main(new String[] {"encrypt", "--with-password", "admin", "--sign-with", "nonExistent.asc"});
|
SopCLI.main(new String[] {"encrypt", "--with-password", "admin", "--sign-with", "nonExistent.asc"});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(1)
|
@ExpectSystemExitWithStatus(67)
|
||||||
public void signWith_keyIsProtectedCausesExit1() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotSign, SOPGPException.BadData, IOException {
|
public void signWith_keyIsProtectedCausesExit67() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotSign, SOPGPException.BadData, IOException {
|
||||||
when(encrypt.signWith(any())).thenThrow(new SOPGPException.KeyIsProtected());
|
when(encrypt.signWith(any())).thenThrow(new SOPGPException.KeyIsProtected());
|
||||||
File keyFile = File.createTempFile("sign-with", ".asc");
|
File keyFile = File.createTempFile("sign-with", ".asc");
|
||||||
SopCLI.main(new String[] {"encrypt", "--sign-with", keyFile.getAbsolutePath(), "--with-password", "starship"});
|
SopCLI.main(new String[] {"encrypt", "--sign-with", keyFile.getAbsolutePath(), "--with-password", "starship"});
|
||||||
|
@ -126,7 +126,7 @@ public class EncryptCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(13)
|
@ExpectSystemExitWithStatus(13)
|
||||||
public void signWith_unsupportedAsymmetricAlgoCausesExit13() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotSign, SOPGPException.BadData, IOException {
|
public void signWith_unsupportedAsymmetricAlgoCausesExit13() throws SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotSign, SOPGPException.BadData, IOException {
|
||||||
when(encrypt.signWith(any())).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo(new Exception()));
|
when(encrypt.signWith(any())).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo("Unsupported asymmetric algorithm.", new Exception()));
|
||||||
File keyFile = File.createTempFile("sign-with", ".asc");
|
File keyFile = File.createTempFile("sign-with", ".asc");
|
||||||
SopCLI.main(new String[] {"encrypt", "--with-password", "123456", "--sign-with", keyFile.getAbsolutePath()});
|
SopCLI.main(new String[] {"encrypt", "--with-password", "123456", "--sign-with", keyFile.getAbsolutePath()});
|
||||||
}
|
}
|
||||||
|
@ -148,15 +148,15 @@ public class EncryptCmdTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(1)
|
@ExpectSystemExitWithStatus(61)
|
||||||
public void cert_nonExistentCertFileCausesExit1() {
|
public void cert_nonExistentCertFileCausesExit61() {
|
||||||
SopCLI.main(new String[] {"encrypt", "invalid.asc"});
|
SopCLI.main(new String[] {"encrypt", "invalid.asc"});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(13)
|
@ExpectSystemExitWithStatus(13)
|
||||||
public void cert_unsupportedAsymmetricAlgorithmCausesExit13() throws IOException, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotEncrypt, SOPGPException.BadData {
|
public void cert_unsupportedAsymmetricAlgorithmCausesExit13() throws IOException, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotEncrypt, SOPGPException.BadData {
|
||||||
when(encrypt.withCert(any())).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo(new Exception()));
|
when(encrypt.withCert(any())).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo("Unsupported asymmetric algorithm.", new Exception()));
|
||||||
File certFile = File.createTempFile("cert", ".asc");
|
File certFile = File.createTempFile("cert", ".asc");
|
||||||
SopCLI.main(new String[] {"encrypt", certFile.getAbsolutePath()});
|
SopCLI.main(new String[] {"encrypt", certFile.getAbsolutePath()});
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ public class EncryptCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(17)
|
@ExpectSystemExitWithStatus(17)
|
||||||
public void cert_certCannotEncryptCausesExit17() throws IOException, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotEncrypt, SOPGPException.BadData {
|
public void cert_certCannotEncryptCausesExit17() throws IOException, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.CertCannotEncrypt, SOPGPException.BadData {
|
||||||
when(encrypt.withCert(any())).thenThrow(new SOPGPException.CertCannotEncrypt());
|
when(encrypt.withCert(any())).thenThrow(new SOPGPException.CertCannotEncrypt("Certificate cannot encrypt.", new Exception()));
|
||||||
File certFile = File.createTempFile("cert", ".asc");
|
File certFile = File.createTempFile("cert", ".asc");
|
||||||
SopCLI.main(new String[] {"encrypt", certFile.getAbsolutePath()});
|
SopCLI.main(new String[] {"encrypt", certFile.getAbsolutePath()});
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ public class GenerateKeyCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(13)
|
@ExpectSystemExitWithStatus(13)
|
||||||
public void unsupportedAsymmetricAlgorithmCausesExit13() throws SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.MissingArg, IOException {
|
public void unsupportedAsymmetricAlgorithmCausesExit13() throws SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.MissingArg, IOException {
|
||||||
when(generateKey.generate()).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo(new Exception()));
|
when(generateKey.generate()).thenThrow(new SOPGPException.UnsupportedAsymmetricAlgo("Unsupported asymmetric algorithm.", new Exception()));
|
||||||
SopCLI.main(new String[] {"generate-key", "Alice"});
|
SopCLI.main(new String[] {"generate-key", "Alice"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class SignCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(37)
|
@ExpectSystemExitWithStatus(37)
|
||||||
public void as_unsupportedOptionCausesExit37() throws SOPGPException.UnsupportedOption {
|
public void as_unsupportedOptionCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||||
when(sign.mode(any())).thenThrow(new SOPGPException.UnsupportedOption());
|
when(sign.mode(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting signing mode not supported."));
|
||||||
SopCLI.main(new String[] {"sign", "--as", "binary", keyFile.getAbsolutePath()});
|
SopCLI.main(new String[] {"sign", "--as", "binary", keyFile.getAbsolutePath()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class VerifyCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(37)
|
@ExpectSystemExitWithStatus(37)
|
||||||
public void notAfter_unsupportedOptionCausesExit37() throws SOPGPException.UnsupportedOption {
|
public void notAfter_unsupportedOptionCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||||
when(verify.notAfter(any())).thenThrow(new SOPGPException.UnsupportedOption());
|
when(verify.notAfter(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting upper signature date boundary not supported."));
|
||||||
SopCLI.main(new String[] {"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()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ public class VerifyCmdTest {
|
||||||
@Test
|
@Test
|
||||||
@ExpectSystemExitWithStatus(37)
|
@ExpectSystemExitWithStatus(37)
|
||||||
public void notBefore_unsupportedOptionCausesExit37() throws SOPGPException.UnsupportedOption {
|
public void notBefore_unsupportedOptionCausesExit37() throws SOPGPException.UnsupportedOption {
|
||||||
when(verify.notBefore(any())).thenThrow(new SOPGPException.UnsupportedOption());
|
when(verify.notBefore(any())).thenThrow(new SOPGPException.UnsupportedOption("Setting lower signature date boundary not supported."));
|
||||||
SopCLI.main(new String[] {"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()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package sop.exception;
|
package sop.exception;
|
||||||
|
|
||||||
public class SOPGPException extends Exception {
|
public abstract class SOPGPException extends RuntimeException {
|
||||||
|
|
||||||
public SOPGPException() {
|
public SOPGPException() {
|
||||||
super();
|
super();
|
||||||
|
@ -29,10 +29,21 @@ public class SOPGPException extends Exception {
|
||||||
super(e);
|
super(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SOPGPException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract int getExitCode();
|
||||||
|
|
||||||
public static class NoSignature extends SOPGPException {
|
public static class NoSignature extends SOPGPException {
|
||||||
|
|
||||||
public static final int EXIT_CODE = 3;
|
public static final int EXIT_CODE = 3;
|
||||||
|
|
||||||
|
public NoSignature() {
|
||||||
|
super("No verifiable signature found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
|
@ -42,10 +53,15 @@ public class SOPGPException extends Exception {
|
||||||
|
|
||||||
public static final int EXIT_CODE = 13;
|
public static final int EXIT_CODE = 13;
|
||||||
|
|
||||||
|
public UnsupportedAsymmetricAlgo(String message, Throwable e) {
|
||||||
|
super(message, e);
|
||||||
|
}
|
||||||
|
|
||||||
public UnsupportedAsymmetricAlgo(Throwable e) {
|
public UnsupportedAsymmetricAlgo(Throwable e) {
|
||||||
super(e);
|
super(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
|
@ -54,12 +70,17 @@ public class SOPGPException extends Exception {
|
||||||
public static class CertCannotEncrypt extends SOPGPException {
|
public static class CertCannotEncrypt extends SOPGPException {
|
||||||
public static final int EXIT_CODE = 17;
|
public static final int EXIT_CODE = 17;
|
||||||
|
|
||||||
|
public CertCannotEncrypt(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CertCannotSign extends SOPGPException {
|
public static class CertCannotSign extends Exception {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +92,7 @@ public class SOPGPException extends Exception {
|
||||||
super(s);
|
super(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +102,11 @@ public class SOPGPException extends Exception {
|
||||||
|
|
||||||
public static final int EXIT_CODE = 23;
|
public static final int EXIT_CODE = 23;
|
||||||
|
|
||||||
|
public IncompleteVerification(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
|
@ -89,6 +116,7 @@ public class SOPGPException extends Exception {
|
||||||
|
|
||||||
public static final int EXIT_CODE = 29;
|
public static final int EXIT_CODE = 29;
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
|
@ -98,6 +126,7 @@ public class SOPGPException extends Exception {
|
||||||
|
|
||||||
public static final int EXIT_CODE = 31;
|
public static final int EXIT_CODE = 31;
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
|
@ -107,6 +136,15 @@ public class SOPGPException extends Exception {
|
||||||
|
|
||||||
public static final int EXIT_CODE = 37;
|
public static final int EXIT_CODE = 37;
|
||||||
|
|
||||||
|
public UnsupportedOption(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnsupportedOption(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
|
@ -120,6 +158,11 @@ public class SOPGPException extends Exception {
|
||||||
super(e);
|
super(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BadData(String message, BadData badData) {
|
||||||
|
super(message, badData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
|
@ -129,6 +172,7 @@ public class SOPGPException extends Exception {
|
||||||
|
|
||||||
public static final int EXIT_CODE = 53;
|
public static final int EXIT_CODE = 53;
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
|
@ -136,20 +180,80 @@ public class SOPGPException extends Exception {
|
||||||
|
|
||||||
public static class OutputExists extends SOPGPException {
|
public static class OutputExists extends SOPGPException {
|
||||||
|
|
||||||
|
public static final int EXIT_CODE = 59;
|
||||||
|
|
||||||
|
public OutputExists(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getExitCode() {
|
||||||
|
return EXIT_CODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MissingInput extends SOPGPException {
|
||||||
|
|
||||||
|
public static final int EXIT_CODE = 61;
|
||||||
|
|
||||||
|
public MissingInput(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getExitCode() {
|
||||||
|
return EXIT_CODE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class KeyIsProtected extends SOPGPException {
|
public static class KeyIsProtected extends SOPGPException {
|
||||||
|
|
||||||
|
public static final int EXIT_CODE = 67;
|
||||||
|
|
||||||
|
public KeyIsProtected() {
|
||||||
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AmbiguousInput extends SOPGPException {
|
public KeyIsProtected(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class NotImplemented extends SOPGPException {
|
@Override
|
||||||
|
public int getExitCode() {
|
||||||
|
return EXIT_CODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class UnsupportedSubcommand extends SOPGPException {
|
||||||
|
|
||||||
public static final int EXIT_CODE = 69;
|
public static final int EXIT_CODE = 69;
|
||||||
|
|
||||||
|
public UnsupportedSubcommand(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getExitCode() {
|
||||||
|
return EXIT_CODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class UnsupportedSpecialPrefix extends SOPGPException {
|
||||||
|
|
||||||
|
public static final int EXIT_CODE = 71;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getExitCode() {
|
||||||
|
return EXIT_CODE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class AmbiguousInput extends SOPGPException {
|
||||||
|
|
||||||
|
public static final int EXIT_CODE = 73;
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getExitCode() {
|
public int getExitCode() {
|
||||||
return EXIT_CODE;
|
return EXIT_CODE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue