Reformat and restructure exceptions

This commit is contained in:
Paul Schaub 2022-06-10 16:16:37 +02:00
parent e175ee6208
commit eefb445916
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
19 changed files with 286 additions and 123 deletions

View file

@ -5,9 +5,7 @@
package sop.cli.picocli.commands; package sop.cli.picocli.commands;
import picocli.CommandLine; import picocli.CommandLine;
import sop.MicAlg; import sop.Ready;
import sop.ReadyWithResult;
import sop.SigningResult;
import sop.cli.picocli.SopCLI; import sop.cli.picocli.SopCLI;
import sop.enums.InlineSignAs; import sop.enums.InlineSignAs;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
@ -15,7 +13,6 @@ import sop.operation.InlineSign;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -43,18 +40,11 @@ public class InlineSignCmd extends AbstractSopCmd {
paramLabel = "PASSWORD") paramLabel = "PASSWORD")
List<String> withKeyPassword = new ArrayList<>(); List<String> withKeyPassword = new ArrayList<>();
@CommandLine.Option(names = "--micalg-out",
descriptionKey = "sop.inline-sign.usage.option.micalg",
paramLabel = "MICALG")
String micAlgOut;
@Override @Override
public void run() { public void run() {
InlineSign inlineSign = throwIfUnsupportedSubcommand( InlineSign inlineSign = throwIfUnsupportedSubcommand(
SopCLI.getSop().inlineSign(), "inline-sign"); SopCLI.getSop().inlineSign(), "inline-sign");
throwIfOutputExists(micAlgOut);
if (type != null) { if (type != null) {
try { try {
inlineSign.mode(type); inlineSign.mode(type);
@ -100,16 +90,8 @@ public class InlineSignCmd extends AbstractSopCmd {
} }
try { try {
ReadyWithResult<SigningResult> ready = inlineSign.data(System.in); Ready ready = inlineSign.data(System.in);
SigningResult result = ready.writeTo(System.out); ready.writeTo(System.out);
MicAlg micAlg = result.getMicAlg();
if (micAlgOut != null) {
// Write micalg out
OutputStream micAlgOutStream = getOutput(micAlgOut);
micAlg.writeTo(micAlgOutStream);
micAlgOutStream.close();
}
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View file

@ -32,7 +32,7 @@ public class ArmorCmdTest {
private SOP sop; private SOP sop;
@BeforeEach @BeforeEach
public void mockComponents() throws SOPGPException.BadData { public void mockComponents() throws SOPGPException.BadData, IOException {
armor = mock(Armor.class); armor = mock(Armor.class);
sop = mock(SOP.class); sop = mock(SOP.class);
when(sop.armor()).thenReturn(armor); when(sop.armor()).thenReturn(armor);
@ -56,7 +56,7 @@ public class ArmorCmdTest {
} }
@Test @Test
public void assertDataIsAlwaysCalled() throws SOPGPException.BadData { public void assertDataIsAlwaysCalled() throws SOPGPException.BadData, IOException {
SopCLI.main(new String[] {"armor"}); SopCLI.main(new String[] {"armor"});
verify(armor, times(1)).data((InputStream) any()); verify(armor, times(1)).data((InputStream) any());
} }
@ -77,7 +77,7 @@ public class ArmorCmdTest {
@Test @Test
@ExpectSystemExitWithStatus(41) @ExpectSystemExitWithStatus(41)
public void ifBadDataExit41() throws SOPGPException.BadData { public void ifBadDataExit41() throws SOPGPException.BadData, IOException {
when(armor.data((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException())); when(armor.data((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
SopCLI.main(new String[] {"armor"}); SopCLI.main(new String[] {"armor"});

View file

@ -48,7 +48,7 @@ public class DecryptCmdTest {
private Decrypt decrypt; private Decrypt decrypt;
@BeforeEach @BeforeEach
public void mockComponents() throws SOPGPException.UnsupportedOption, SOPGPException.MissingArg, SOPGPException.BadData, SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.PasswordNotHumanReadable, SOPGPException.CannotDecrypt { public void mockComponents() throws SOPGPException.UnsupportedOption, SOPGPException.MissingArg, SOPGPException.BadData, SOPGPException.KeyIsProtected, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.PasswordNotHumanReadable, SOPGPException.CannotDecrypt, IOException {
SOP sop = mock(SOP.class); SOP sop = mock(SOP.class);
decrypt = mock(Decrypt.class); decrypt = mock(Decrypt.class);
@ -75,14 +75,14 @@ public class DecryptCmdTest {
@Test @Test
@ExpectSystemExitWithStatus(19) @ExpectSystemExitWithStatus(19)
public void missingArgumentsExceptionCausesExit19() throws SOPGPException.MissingArg, SOPGPException.BadData, SOPGPException.CannotDecrypt { public void missingArgumentsExceptionCausesExit19() throws SOPGPException.MissingArg, SOPGPException.BadData, SOPGPException.CannotDecrypt, IOException {
when(decrypt.ciphertext((InputStream) any())).thenThrow(new SOPGPException.MissingArg("Missing arguments.")); when(decrypt.ciphertext((InputStream) any())).thenThrow(new SOPGPException.MissingArg("Missing arguments."));
SopCLI.main(new String[] {"decrypt"}); SopCLI.main(new String[] {"decrypt"});
} }
@Test @Test
@ExpectSystemExitWithStatus(41) @ExpectSystemExitWithStatus(41)
public void badDataExceptionCausesExit41() throws SOPGPException.MissingArg, SOPGPException.BadData, SOPGPException.CannotDecrypt { public void badDataExceptionCausesExit41() throws SOPGPException.MissingArg, SOPGPException.BadData, SOPGPException.CannotDecrypt, IOException {
when(decrypt.ciphertext((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException())); when(decrypt.ciphertext((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
SopCLI.main(new String[] {"decrypt"}); SopCLI.main(new String[] {"decrypt"});
} }
@ -223,14 +223,14 @@ public class DecryptCmdTest {
@Test @Test
@ExpectSystemExitWithStatus(29) @ExpectSystemExitWithStatus(29)
public void assertUnableToDecryptExceptionResultsInExit29() throws SOPGPException.CannotDecrypt, SOPGPException.MissingArg, SOPGPException.BadData { public void assertUnableToDecryptExceptionResultsInExit29() throws SOPGPException.CannotDecrypt, SOPGPException.MissingArg, SOPGPException.BadData, IOException {
when(decrypt.ciphertext((InputStream) any())).thenThrow(new SOPGPException.CannotDecrypt()); when(decrypt.ciphertext((InputStream) any())).thenThrow(new SOPGPException.CannotDecrypt());
SopCLI.main(new String[] {"decrypt"}); SopCLI.main(new String[] {"decrypt"});
} }
@Test @Test
@ExpectSystemExitWithStatus(3) @ExpectSystemExitWithStatus(3)
public void assertNoSignatureExceptionCausesExit3() throws SOPGPException.CannotDecrypt, SOPGPException.MissingArg, SOPGPException.BadData { public void assertNoSignatureExceptionCausesExit3() throws SOPGPException.CannotDecrypt, SOPGPException.MissingArg, SOPGPException.BadData, IOException {
when(decrypt.ciphertext((InputStream) any())).thenReturn(new ReadyWithResult<DecryptionResult>() { when(decrypt.ciphertext((InputStream) any())).thenReturn(new ReadyWithResult<DecryptionResult>() {
@Override @Override
public DecryptionResult writeTo(OutputStream outputStream) throws SOPGPException.NoSignature { public DecryptionResult writeTo(OutputStream outputStream) throws SOPGPException.NoSignature {

View file

@ -145,7 +145,7 @@ public class VerifyCmdTest {
@Test @Test
@ExpectSystemExitWithStatus(41) @ExpectSystemExitWithStatus(41)
public void cert_badDataCausesExit41() throws SOPGPException.BadData { public void cert_badDataCausesExit41() throws SOPGPException.BadData, IOException {
when(detachedVerify.cert((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException())); when(detachedVerify.cert((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), cert.getAbsolutePath()}); SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), cert.getAbsolutePath()});
} }
@ -158,7 +158,7 @@ public class VerifyCmdTest {
@Test @Test
@ExpectSystemExitWithStatus(41) @ExpectSystemExitWithStatus(41)
public void signature_badDataCausesExit41() throws SOPGPException.BadData { public void signature_badDataCausesExit41() throws SOPGPException.BadData, IOException {
when(detachedVerify.signatures((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException())); when(detachedVerify.signatures((InputStream) any())).thenThrow(new SOPGPException.BadData(new IOException()));
SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), cert.getAbsolutePath()}); SopCLI.main(new String[] {"verify", signature.getAbsolutePath(), cert.getAbsolutePath()});
} }

View file

@ -240,7 +240,7 @@ public abstract class SOPGPException extends RuntimeException {
} }
/** /**
* A KEYS input is protected (locked) with a password, and sop cannot unlock it. * A KEYS input is protected (locked) with a password and sop failed to unlock it.
*/ */
public static class KeyIsProtected extends SOPGPException { public static class KeyIsProtected extends SOPGPException {
@ -313,8 +313,7 @@ public abstract class SOPGPException extends RuntimeException {
} }
/** /**
* Key not signature-capable (e.g. expired, revoked, unacceptable usage flags) * Key not signature-capable (e.g. expired, revoked, unacceptable usage flags).
* (sop sign and sop encrypt with --sign-with).
*/ */
public static class KeyCannotSign extends SOPGPException { public static class KeyCannotSign extends SOPGPException {
@ -324,8 +323,8 @@ public abstract class SOPGPException extends RuntimeException {
super(); super();
} }
public KeyCannotSign(String s, KeyCannotSign keyCannotSign) { public KeyCannotSign(String s, Throwable throwable) {
super(s, keyCannotSign); super(s, throwable);
} }
@Override @Override

View file

@ -4,8 +4,6 @@
package sop.operation; package sop.operation;
import sop.ReadyWithResult;
import sop.SigningResult;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -28,11 +26,16 @@ public interface AbstractSign<T> {
* @param key input stream containing encoded keys * @param key input stream containing encoded keys
* @return builder instance * @return builder instance
* *
* @throws sop.exception.SOPGPException.KeyIsProtected if the key is password protected * @throws sop.exception.SOPGPException.KeyCannotSign if the key cannot be used for signing
* @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not contain an OpenPGP key * @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not contain an OpenPGP key
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the key uses an unsupported asymmetric algorithm
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
*/ */
T key(InputStream key) throws SOPGPException.KeyIsProtected, SOPGPException.BadData, IOException; T key(InputStream key)
throws SOPGPException.KeyCannotSign,
SOPGPException.BadData,
SOPGPException.UnsupportedAsymmetricAlgo,
IOException;
/** /**
* Add one or more signing keys. * Add one or more signing keys.
@ -40,11 +43,16 @@ public interface AbstractSign<T> {
* @param key byte array containing encoded keys * @param key byte array containing encoded keys
* @return builder instance * @return builder instance
* *
* @throws sop.exception.SOPGPException.KeyIsProtected if the key is password protected * @throws sop.exception.SOPGPException.KeyCannotSign if the key cannot be used for signing
* @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP key * @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP key
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the key uses an unsupported asymmetric algorithm
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
*/ */
default T key(byte[] key) throws SOPGPException.KeyIsProtected, SOPGPException.BadData, IOException { default T key(byte[] key)
throws SOPGPException.KeyCannotSign,
SOPGPException.BadData,
SOPGPException.UnsupportedAsymmetricAlgo,
IOException {
return key(new ByteArrayInputStream(key)); return key(new ByteArrayInputStream(key));
} }
@ -53,8 +61,12 @@ public interface AbstractSign<T> {
* *
* @param password password * @param password password
* @return builder instance * @return builder instance
* @throws sop.exception.SOPGPException.UnsupportedOption if key passwords are not supported
* @throws sop.exception.SOPGPException.PasswordNotHumanReadable if the provided passphrase is not human-readable
*/ */
default T withKeyPassword(String password) { default T withKeyPassword(String password)
throws SOPGPException.UnsupportedOption,
SOPGPException.PasswordNotHumanReadable {
return withKeyPassword(password.getBytes(Charset.forName("UTF8"))); return withKeyPassword(password.getBytes(Charset.forName("UTF8")));
} }
@ -63,30 +75,11 @@ public interface AbstractSign<T> {
* *
* @param password password * @param password password
* @return builder instance * @return builder instance
* @throws sop.exception.SOPGPException.UnsupportedOption if key passwords are not supported
* @throws sop.exception.SOPGPException.PasswordNotHumanReadable if the provided passphrase is not human-readable
*/ */
T withKeyPassword(byte[] password); T withKeyPassword(byte[] password)
throws SOPGPException.UnsupportedOption,
SOPGPException.PasswordNotHumanReadable;
/**
* Signs data.
*
* @param data input stream containing data
* @return ready
*
* @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.ExpectedText if text data was expected, but binary data was encountered
*/
ReadyWithResult<SigningResult> data(InputStream data) throws IOException, SOPGPException.ExpectedText;
/**
* Signs data.
*
* @param data byte array containing data
* @return ready
*
* @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.ExpectedText if text data was expected, but binary data was encountered
*/
default ReadyWithResult<SigningResult> data(byte[] data) throws IOException, SOPGPException.ExpectedText {
return data(new ByteArrayInputStream(data));
}
} }

View file

@ -7,6 +7,7 @@ package sop.operation;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Date; import java.util.Date;
@ -24,7 +25,8 @@ public interface AbstractVerify<T> {
* @param timestamp timestamp * @param timestamp timestamp
* @return builder instance * @return builder instance
*/ */
T notBefore(Date timestamp) throws SOPGPException.UnsupportedOption; T notBefore(Date timestamp)
throws SOPGPException.UnsupportedOption;
/** /**
* Makes the SOP implementation consider signatures after this date invalid. * Makes the SOP implementation consider signatures after this date invalid.
@ -32,23 +34,34 @@ public interface AbstractVerify<T> {
* @param timestamp timestamp * @param timestamp timestamp
* @return builder instance * @return builder instance
*/ */
T notAfter(Date timestamp) throws SOPGPException.UnsupportedOption; T notAfter(Date timestamp)
throws SOPGPException.UnsupportedOption;
/** /**
* Add one or more verification cert. * Add one or more verification cert.
* *
* @param cert input stream containing the encoded certs * @param cert input stream containing the encoded certs
* @return builder instance * @return builder instance
*
* @throws sop.exception.SOPGPException.BadData if the input stream does not contain an OpenPGP certificate
* @throws IOException in case of an IO error
*/ */
T cert(InputStream cert) throws SOPGPException.BadData; T cert(InputStream cert)
throws SOPGPException.BadData,
IOException;
/** /**
* Add one or more verification cert. * Add one or more verification cert.
* *
* @param cert byte array containing the encoded certs * @param cert byte array containing the encoded certs
* @return builder instance * @return builder instance
*
* @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP certificate
* @throws IOException in case of an IO error
*/ */
default T cert(byte[] cert) throws SOPGPException.BadData { default T cert(byte[] cert)
throws SOPGPException.BadData,
IOException {
return cert(new ByteArrayInputStream(cert)); return cert(new ByteArrayInputStream(cert));
} }

View file

@ -5,6 +5,7 @@
package sop.operation; package sop.operation;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import sop.Ready; import sop.Ready;
@ -19,23 +20,34 @@ public interface Armor {
* @param label armor label * @param label armor label
* @return builder instance * @return builder instance
*/ */
Armor label(ArmorLabel label) throws SOPGPException.UnsupportedOption; Armor label(ArmorLabel label)
throws SOPGPException.UnsupportedOption;
/** /**
* Armor the provided data. * Armor the provided data.
* *
* @param data input stream of unarmored OpenPGP data * @param data input stream of unarmored OpenPGP data
* @return armored data * @return armored data
*
* @throws sop.exception.SOPGPException.BadData if the data appears to be OpenPGP packets, but those are broken
* @throws IOException in case of an IO error
*/ */
Ready data(InputStream data) throws SOPGPException.BadData; Ready data(InputStream data)
throws SOPGPException.BadData,
IOException;
/** /**
* Armor the provided data. * Armor the provided data.
* *
* @param data unarmored OpenPGP data * @param data unarmored OpenPGP data
* @return armored data * @return armored data
*
* @throws sop.exception.SOPGPException.BadData if the data appears to be OpenPGP packets, but those are broken
* @throws IOException in case of an IO error
*/ */
default Ready data(byte[] data) throws SOPGPException.BadData { default Ready data(byte[] data)
throws SOPGPException.BadData,
IOException {
return data(new ByteArrayInputStream(data)); return data(new ByteArrayInputStream(data));
} }
} }

View file

@ -22,7 +22,9 @@ public interface Dearmor {
* @throws sop.exception.SOPGPException.BadData in case of non-OpenPGP data * @throws sop.exception.SOPGPException.BadData in case of non-OpenPGP data
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
*/ */
Ready data(InputStream data) throws SOPGPException.BadData, IOException; Ready data(InputStream data)
throws SOPGPException.BadData,
IOException;
/** /**
* Dearmor armored OpenPGP data. * Dearmor armored OpenPGP data.
@ -33,7 +35,9 @@ public interface Dearmor {
* @throws sop.exception.SOPGPException.BadData in case of non-OpenPGP data * @throws sop.exception.SOPGPException.BadData in case of non-OpenPGP data
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
*/ */
default Ready data(byte[] data) throws SOPGPException.BadData, IOException { default Ready data(byte[] data)
throws SOPGPException.BadData,
IOException {
return data(new ByteArrayInputStream(data)); return data(new ByteArrayInputStream(data));
} }
} }

View file

@ -46,10 +46,12 @@ public interface Decrypt {
* @return builder instance * @return builder instance
* *
* @throws sop.exception.SOPGPException.BadData if the {@link InputStream} doesn't provide an OpenPGP certificate * @throws sop.exception.SOPGPException.BadData if the {@link InputStream} doesn't provide an OpenPGP certificate
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the cert uses an unsupported asymmetric algorithm
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
*/ */
Decrypt verifyWithCert(InputStream cert) Decrypt verifyWithCert(InputStream cert)
throws SOPGPException.BadData, throws SOPGPException.BadData,
SOPGPException.UnsupportedAsymmetricAlgo,
IOException; IOException;
/** /**
@ -59,10 +61,13 @@ public interface Decrypt {
* @return builder instance * @return builder instance
* *
* @throws sop.exception.SOPGPException.BadData if the byte array doesn't contain an OpenPGP certificate * @throws sop.exception.SOPGPException.BadData if the byte array doesn't contain an OpenPGP certificate
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the cert uses an unsupported asymmetric algorithm
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
*/ */
default Decrypt verifyWithCert(byte[] cert) default Decrypt verifyWithCert(byte[] cert)
throws SOPGPException.BadData, IOException { throws SOPGPException.BadData,
SOPGPException.UnsupportedAsymmetricAlgo,
IOException {
return verifyWithCert(new ByteArrayInputStream(cert)); return verifyWithCert(new ByteArrayInputStream(cert));
} }
@ -98,10 +103,12 @@ public interface Decrypt {
* *
* @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not provide an OpenPGP key * @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not provide an OpenPGP key
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the key uses an unsupported asymmetric algorithm * @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the key uses an unsupported asymmetric algorithm
* @throws IOException in case of an IO error
*/ */
Decrypt withKey(InputStream key) Decrypt withKey(InputStream key)
throws SOPGPException.BadData, throws SOPGPException.BadData,
SOPGPException.UnsupportedAsymmetricAlgo; SOPGPException.UnsupportedAsymmetricAlgo,
IOException;
/** /**
* Adds one or more decryption key. * Adds one or more decryption key.
@ -109,14 +116,14 @@ public interface Decrypt {
* @param key byte array containing the key(s) * @param key byte array containing the key(s)
* @return builder instance * @return builder instance
* *
* @throws sop.exception.SOPGPException.KeyIsProtected if the key is password protected
* @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP key * @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP key
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the key uses an unsupported asymmetric algorithm * @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the key uses an unsupported asymmetric algorithm
* @throws IOException in case of an IO error
*/ */
default Decrypt withKey(byte[] key) default Decrypt withKey(byte[] key)
throws SOPGPException.KeyIsProtected, throws SOPGPException.BadData,
SOPGPException.BadData, SOPGPException.UnsupportedAsymmetricAlgo,
SOPGPException.UnsupportedAsymmetricAlgo { IOException {
return withKey(new ByteArrayInputStream(key)); return withKey(new ByteArrayInputStream(key));
} }
@ -125,8 +132,12 @@ public interface Decrypt {
* *
* @param password password * @param password password
* @return builder instance * @return builder instance
* @throws sop.exception.SOPGPException.UnsupportedOption if the implementation does not support key passwords
* @throws sop.exception.SOPGPException.PasswordNotHumanReadable if the password is not human-readable
*/ */
default Decrypt withKeyPassword(String password) { default Decrypt withKeyPassword(String password)
throws SOPGPException.UnsupportedOption,
SOPGPException.PasswordNotHumanReadable {
return withKeyPassword(password.getBytes(Charset.forName("UTF8"))); return withKeyPassword(password.getBytes(Charset.forName("UTF8")));
} }
@ -135,8 +146,12 @@ public interface Decrypt {
* *
* @param password password * @param password password
* @return builder instance * @return builder instance
* @throws sop.exception.SOPGPException.UnsupportedOption if the implementation does not support key passwords
* @throws sop.exception.SOPGPException.PasswordNotHumanReadable if the password is not human-readable
*/ */
Decrypt withKeyPassword(byte[] password); Decrypt withKeyPassword(byte[] password)
throws SOPGPException.UnsupportedOption,
SOPGPException.PasswordNotHumanReadable;
/** /**
* Decrypts the given ciphertext, returning verification results and plaintext. * Decrypts the given ciphertext, returning verification results and plaintext.
@ -144,11 +159,17 @@ public interface Decrypt {
* @return ready with result * @return ready with result
* *
* @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not provide an OpenPGP message * @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not provide an OpenPGP message
* @throws sop.exception.SOPGPException.MissingArg in case of missing decryption method (password or key required) * @throws sop.exception.SOPGPException.MissingArg if an argument required for decryption was not provided
* @throws sop.exception.SOPGPException.CannotDecrypt in case decryption fails for some reason * @throws sop.exception.SOPGPException.CannotDecrypt in case decryption fails for some reason
* @throws sop.exception.SOPGPException.KeyIsProtected if the decryption key cannot be unlocked (e.g. missing passphrase)
* @throws IOException in case of an IO error
*/ */
ReadyWithResult<DecryptionResult> ciphertext(InputStream ciphertext) ReadyWithResult<DecryptionResult> ciphertext(InputStream ciphertext)
throws SOPGPException.BadData, SOPGPException.MissingArg, SOPGPException.CannotDecrypt; throws SOPGPException.BadData,
SOPGPException.MissingArg,
SOPGPException.CannotDecrypt,
SOPGPException.KeyIsProtected,
IOException;
/** /**
* Decrypts the given ciphertext, returning verification results and plaintext. * Decrypts the given ciphertext, returning verification results and plaintext.
@ -158,9 +179,15 @@ public interface Decrypt {
* @throws sop.exception.SOPGPException.BadData if the byte array does not contain an encrypted OpenPGP message * @throws sop.exception.SOPGPException.BadData if the byte array does not contain an encrypted OpenPGP message
* @throws sop.exception.SOPGPException.MissingArg in case of missing decryption method (password or key required) * @throws sop.exception.SOPGPException.MissingArg in case of missing decryption method (password or key required)
* @throws sop.exception.SOPGPException.CannotDecrypt in case decryption fails for some reason * @throws sop.exception.SOPGPException.CannotDecrypt in case decryption fails for some reason
* @throws sop.exception.SOPGPException.KeyIsProtected if the decryption key cannot be unlocked (e.g. missing passphrase)
* @throws IOException in case of an IO error
*/ */
default ReadyWithResult<DecryptionResult> ciphertext(byte[] ciphertext) default ReadyWithResult<DecryptionResult> ciphertext(byte[] ciphertext)
throws SOPGPException.BadData, SOPGPException.MissingArg, SOPGPException.CannotDecrypt { throws SOPGPException.BadData,
SOPGPException.MissingArg,
SOPGPException.CannotDecrypt,
SOPGPException.KeyIsProtected,
IOException {
return ciphertext(new ByteArrayInputStream(ciphertext)); return ciphertext(new ByteArrayInputStream(ciphertext));
} }
} }

View file

@ -4,9 +4,13 @@
package sop.operation; package sop.operation;
import sop.ReadyWithResult;
import sop.SigningResult;
import sop.enums.SignAs; import sop.enums.SignAs;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
public interface DetachedSign extends AbstractSign<DetachedSign> { public interface DetachedSign extends AbstractSign<DetachedSign> {
@ -20,6 +24,38 @@ public interface DetachedSign extends AbstractSign<DetachedSign> {
* *
* @throws sop.exception.SOPGPException.UnsupportedOption if this option is not supported * @throws sop.exception.SOPGPException.UnsupportedOption if this option is not supported
*/ */
DetachedSign mode(SignAs mode) throws SOPGPException.UnsupportedOption; DetachedSign mode(SignAs mode)
throws SOPGPException.UnsupportedOption;
/**
* Signs data.
*
* @param data input stream containing data
* @return ready
*
* @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.KeyIsProtected if at least one signing key cannot be unlocked
* @throws sop.exception.SOPGPException.ExpectedText if text data was expected, but binary data was encountered
*/
ReadyWithResult<SigningResult> data(InputStream data)
throws IOException,
SOPGPException.KeyIsProtected,
SOPGPException.ExpectedText;
/**
* Signs data.
*
* @param data byte array containing data
* @return ready
*
* @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.KeyIsProtected if at least one signing key cannot be unlocked
* @throws sop.exception.SOPGPException.ExpectedText if text data was expected, but binary data was encountered
*/
default ReadyWithResult<SigningResult> data(byte[] data)
throws IOException,
SOPGPException.KeyIsProtected,
SOPGPException.ExpectedText {
return data(new ByteArrayInputStream(data));
}
} }

View file

@ -7,6 +7,7 @@ package sop.operation;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
/** /**
@ -19,16 +20,26 @@ public interface DetachedVerify extends AbstractVerify<DetachedVerify>, VerifySi
* @param signatures input stream containing encoded, detached signatures. * @param signatures input stream containing encoded, detached signatures.
* *
* @return builder instance * @return builder instance
*
* @throws sop.exception.SOPGPException.BadData if the input stream does not contain OpenPGP signatures
* @throws IOException in case of an IO error
*/ */
VerifySignatures signatures(InputStream signatures) throws SOPGPException.BadData; VerifySignatures signatures(InputStream signatures)
throws SOPGPException.BadData,
IOException;
/** /**
* Provides the detached signatures. * Provides the detached signatures.
* @param signatures byte array containing encoded, detached signatures. * @param signatures byte array containing encoded, detached signatures.
* *
* @return builder instance * @return builder instance
*
* @throws sop.exception.SOPGPException.BadData if the byte array does not contain OpenPGP signatures
* @throws IOException in case of an IO error
*/ */
default VerifySignatures signatures(byte[] signatures) throws SOPGPException.BadData { default VerifySignatures signatures(byte[] signatures)
throws SOPGPException.BadData,
IOException {
return signatures(new ByteArrayInputStream(signatures)); return signatures(new ByteArrayInputStream(signatures));
} }
} }

View file

@ -39,16 +39,16 @@ public interface Encrypt {
* @param key input stream containing the encoded signer key * @param key input stream containing the encoded signer key
* @return builder instance * @return builder instance
* *
* @throws sop.exception.SOPGPException.KeyIsProtected if the key is password protected * @throws sop.exception.SOPGPException.KeyCannotSign if the key cannot be used for signing
* @throws sop.exception.SOPGPException.KeyCannotSign if the key is not capable of signing
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the key uses an unsupported asymmetric algorithm * @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the key uses an unsupported asymmetric algorithm
* @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not contain an OpenPGP key * @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not contain an OpenPGP key
* @throws IOException in case of an IO error
*/ */
Encrypt signWith(InputStream key) Encrypt signWith(InputStream key)
throws SOPGPException.KeyIsProtected, throws SOPGPException.KeyCannotSign,
SOPGPException.KeyCannotSign,
SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.UnsupportedAsymmetricAlgo,
SOPGPException.BadData; SOPGPException.BadData,
IOException;
/** /**
* Adds the signer key. * Adds the signer key.
@ -56,16 +56,16 @@ public interface Encrypt {
* @param key byte array containing the encoded signer key * @param key byte array containing the encoded signer key
* @return builder instance * @return builder instance
* *
* @throws sop.exception.SOPGPException.KeyIsProtected if the key is password protected * @throws sop.exception.SOPGPException.KeyCannotSign if the key cannot be used for signing
* @throws sop.exception.SOPGPException.KeyCannotSign if the key is not capable of signing
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the key uses an unsupported asymmetric algorithm * @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the key uses an unsupported asymmetric algorithm
* @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP key * @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP key
* @throws IOException in case of an IO error
*/ */
default Encrypt signWith(byte[] key) default Encrypt signWith(byte[] key)
throws SOPGPException.KeyIsProtected, throws SOPGPException.KeyCannotSign,
SOPGPException.KeyCannotSign,
SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.UnsupportedAsymmetricAlgo,
SOPGPException.BadData { SOPGPException.BadData,
IOException {
return signWith(new ByteArrayInputStream(key)); return signWith(new ByteArrayInputStream(key));
} }
@ -74,18 +74,28 @@ public interface Encrypt {
* *
* @param password password * @param password password
* @return builder instance * @return builder instance
*
* @throws sop.exception.SOPGPException.PasswordNotHumanReadable if the password is not human-readable
* @throws sop.exception.SOPGPException.UnsupportedOption if key password are not supported
*/ */
default Encrypt withKeyPassword(String password) { default Encrypt withKeyPassword(String password)
throws SOPGPException.PasswordNotHumanReadable,
SOPGPException.UnsupportedOption {
return withKeyPassword(password.getBytes(Charset.forName("UTF8"))); return withKeyPassword(password.getBytes(Charset.forName("UTF8")));
} }
/** /**
* Provide the password for the secret key used for sigining. * Provide the password for the secret key used for signing.
* *
* @param password password * @param password password
* @return builder instance * @return builder instance
*
* @throws sop.exception.SOPGPException.PasswordNotHumanReadable if the password is not human-readable
* @throws sop.exception.SOPGPException.UnsupportedOption if key password are not supported
*/ */
Encrypt withKeyPassword(byte[] password); Encrypt withKeyPassword(byte[] password)
throws SOPGPException.PasswordNotHumanReadable,
SOPGPException.UnsupportedOption;
/** /**
* Encrypt with the given password. * Encrypt with the given password.
@ -109,11 +119,13 @@ public interface Encrypt {
* @throws sop.exception.SOPGPException.CertCannotEncrypt if the certificate is not encryption capable * @throws sop.exception.SOPGPException.CertCannotEncrypt if the certificate is not encryption capable
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the certificate uses an unsupported asymmetric algorithm * @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the certificate uses an unsupported asymmetric algorithm
* @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not contain an OpenPGP certificate * @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not contain an OpenPGP certificate
* @throws IOException in case of an IO error
*/ */
Encrypt withCert(InputStream cert) Encrypt withCert(InputStream cert)
throws SOPGPException.CertCannotEncrypt, throws SOPGPException.CertCannotEncrypt,
SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.UnsupportedAsymmetricAlgo,
SOPGPException.BadData; SOPGPException.BadData,
IOException;
/** /**
* Encrypt with the given cert. * Encrypt with the given cert.
@ -124,11 +136,13 @@ public interface Encrypt {
* @throws sop.exception.SOPGPException.CertCannotEncrypt if the certificate is not encryption capable * @throws sop.exception.SOPGPException.CertCannotEncrypt if the certificate is not encryption capable
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the certificate uses an unsupported asymmetric algorithm * @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the certificate uses an unsupported asymmetric algorithm
* @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP certificate * @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP certificate
* @throws IOException in case of an IO error
*/ */
default Encrypt withCert(byte[] cert) default Encrypt withCert(byte[] cert)
throws SOPGPException.CertCannotEncrypt, throws SOPGPException.CertCannotEncrypt,
SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.UnsupportedAsymmetricAlgo,
SOPGPException.BadData { SOPGPException.BadData,
IOException {
return withCert(new ByteArrayInputStream(cert)); return withCert(new ByteArrayInputStream(cert));
} }
@ -138,9 +152,11 @@ public interface Encrypt {
* @return input stream containing the ciphertext * @return input stream containing the ciphertext
* *
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.KeyIsProtected if at least one signing key cannot be unlocked
*/ */
Ready plaintext(InputStream plaintext) Ready plaintext(InputStream plaintext)
throws IOException; throws IOException,
SOPGPException.KeyIsProtected;
/** /**
* Encrypt the given data yielding the ciphertext. * Encrypt the given data yielding the ciphertext.
@ -148,8 +164,11 @@ public interface Encrypt {
* @return input stream containing the ciphertext * @return input stream containing the ciphertext
* *
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.KeyIsProtected if at least one signing key cannot be unlocked
*/ */
default Ready plaintext(byte[] plaintext) throws IOException { default Ready plaintext(byte[] plaintext)
throws IOException,
SOPGPException.KeyIsProtected {
return plaintext(new ByteArrayInputStream(plaintext)); return plaintext(new ByteArrayInputStream(plaintext));
} }
} }

View file

@ -29,7 +29,9 @@ public interface ExtractCert {
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not contain an OpenPGP key * @throws sop.exception.SOPGPException.BadData if the {@link InputStream} does not contain an OpenPGP key
*/ */
Ready key(InputStream keyInputStream) throws IOException, SOPGPException.BadData; Ready key(InputStream keyInputStream)
throws IOException,
SOPGPException.BadData;
/** /**
* Extract the cert(s) from the provided key(s). * Extract the cert(s) from the provided key(s).
@ -40,7 +42,9 @@ public interface ExtractCert {
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP key * @throws sop.exception.SOPGPException.BadData if the byte array does not contain an OpenPGP key
*/ */
default Ready key(byte[] key) throws IOException, SOPGPException.BadData { default Ready key(byte[] key)
throws IOException,
SOPGPException.BadData {
return key(new ByteArrayInputStream(key)); return key(new ByteArrayInputStream(key));
} }
} }

View file

@ -33,8 +33,13 @@ public interface GenerateKey {
* *
* @param password password to protect the key * @param password password to protect the key
* @return builder instance * @return builder instance
*
* @throws sop.exception.SOPGPException.UnsupportedOption if key passwords are not supported
* @throws sop.exception.SOPGPException.PasswordNotHumanReadable if the password is not human-readable
*/ */
GenerateKey withKeyPassword(String password); GenerateKey withKeyPassword(String password)
throws SOPGPException.PasswordNotHumanReadable,
SOPGPException.UnsupportedOption;
/** /**
* Set a password for the key. * Set a password for the key.
@ -42,10 +47,12 @@ public interface GenerateKey {
* @param password password to protect the key * @param password password to protect the key
* @return builder instance * @return builder instance
* *
* @throws sop.exception.SOPGPException.PasswordNotHumanReadable in case of a non-UTF8 password * @throws sop.exception.SOPGPException.PasswordNotHumanReadable if the password is not human-readable
* @throws sop.exception.SOPGPException.UnsupportedOption if key passwords are not supported
*/ */
default GenerateKey withKeyPassword(byte[] password) default GenerateKey withKeyPassword(byte[] password)
throws SOPGPException.PasswordNotHumanReadable { throws SOPGPException.PasswordNotHumanReadable,
SOPGPException.UnsupportedOption {
return withKeyPassword(UTF8Util.decodeUTF8(password)); return withKeyPassword(UTF8Util.decodeUTF8(password));
} }
@ -58,5 +65,8 @@ public interface GenerateKey {
* @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the generated key uses an unsupported asymmetric algorithm * @throws sop.exception.SOPGPException.UnsupportedAsymmetricAlgo if the generated key uses an unsupported asymmetric algorithm
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
*/ */
Ready generate() throws SOPGPException.MissingArg, SOPGPException.UnsupportedAsymmetricAlgo, IOException; Ready generate()
throws SOPGPException.MissingArg,
SOPGPException.UnsupportedAsymmetricAlgo,
IOException;
} }

View file

@ -10,6 +10,7 @@ import java.io.InputStream;
import sop.ReadyWithResult; import sop.ReadyWithResult;
import sop.Signatures; import sop.Signatures;
import sop.exception.SOPGPException;
/** /**
* Split cleartext signed messages up into data and signatures. * Split cleartext signed messages up into data and signatures.
@ -23,13 +24,17 @@ public interface InlineDetach {
InlineDetach noArmor(); InlineDetach noArmor();
/** /**
* Detach the provided cleartext signed message from its signatures. * Detach the provided signed message from its signatures.
* *
* @param messageInputStream input stream containing the signed message * @param messageInputStream input stream containing the signed message
* @return result containing the detached message * @return result containing the detached message
*
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.BadData if the input stream does not contain a signed message
*/ */
ReadyWithResult<Signatures> message(InputStream messageInputStream) throws IOException; ReadyWithResult<Signatures> message(InputStream messageInputStream)
throws IOException,
SOPGPException.BadData;
/** /**
* Detach the provided cleartext signed message from its signatures. * Detach the provided cleartext signed message from its signatures.
@ -37,8 +42,11 @@ public interface InlineDetach {
* @param message byte array containing the signed message * @param message byte array containing the signed message
* @return result containing the detached message * @return result containing the detached message
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.BadData if the byte array does not contain a signed message
*/ */
default ReadyWithResult<Signatures> message(byte[] message) throws IOException { default ReadyWithResult<Signatures> message(byte[] message)
throws IOException,
SOPGPException.BadData {
return message(new ByteArrayInputStream(message)); return message(new ByteArrayInputStream(message));
} }
} }

View file

@ -4,9 +4,12 @@
package sop.operation; package sop.operation;
import sop.Ready;
import sop.enums.InlineSignAs; import sop.enums.InlineSignAs;
import sop.exception.SOPGPException; import sop.exception.SOPGPException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
public interface InlineSign extends AbstractSign<InlineSign> { public interface InlineSign extends AbstractSign<InlineSign> {
@ -20,6 +23,38 @@ public interface InlineSign extends AbstractSign<InlineSign> {
* *
* @throws sop.exception.SOPGPException.UnsupportedOption if this option is not supported * @throws sop.exception.SOPGPException.UnsupportedOption if this option is not supported
*/ */
InlineSign mode(InlineSignAs mode) throws SOPGPException.UnsupportedOption; InlineSign mode(InlineSignAs mode)
throws SOPGPException.UnsupportedOption;
/**
* Signs data.
*
* @param data input stream containing data
* @return ready
*
* @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.KeyIsProtected if at least one signing key cannot be unlocked
* @throws sop.exception.SOPGPException.ExpectedText if text data was expected, but binary data was encountered
*/
Ready data(InputStream data)
throws IOException,
SOPGPException.KeyIsProtected,
SOPGPException.ExpectedText;
/**
* Signs data.
*
* @param data byte array containing data
* @return ready
*
* @throws IOException in case of an IO error
* @throws sop.exception.SOPGPException.KeyIsProtected if at least one signing key cannot be unlocked
* @throws sop.exception.SOPGPException.ExpectedText if text data was expected, but binary data was encountered
*/
default Ready data(byte[] data)
throws IOException,
SOPGPException.KeyIsProtected,
SOPGPException.ExpectedText {
return data(new ByteArrayInputStream(data));
}
} }

View file

@ -30,7 +30,9 @@ public interface InlineVerify extends AbstractVerify<InlineVerify> {
* @throws SOPGPException.BadData when the data is invalid OpenPGP data * @throws SOPGPException.BadData when the data is invalid OpenPGP data
*/ */
ReadyWithResult<List<Verification>> data(InputStream data) ReadyWithResult<List<Verification>> data(InputStream data)
throws IOException, SOPGPException.NoSignature, SOPGPException.BadData; throws IOException,
SOPGPException.NoSignature,
SOPGPException.BadData;
/** /**
* Provide the inline-signed data. * Provide the inline-signed data.
@ -44,7 +46,9 @@ public interface InlineVerify extends AbstractVerify<InlineVerify> {
* @throws SOPGPException.BadData when the data is invalid OpenPGP data * @throws SOPGPException.BadData when the data is invalid OpenPGP data
*/ */
default ReadyWithResult<List<Verification>> data(byte[] data) default ReadyWithResult<List<Verification>> data(byte[] data)
throws IOException, SOPGPException.NoSignature, SOPGPException.BadData { throws IOException,
SOPGPException.NoSignature,
SOPGPException.BadData {
return data(new ByteArrayInputStream(data)); return data(new ByteArrayInputStream(data));
} }
} }

View file

@ -20,10 +20,13 @@ public interface VerifySignatures {
* @param data signed data * @param data signed data
* @return list of signature verifications * @return list of signature verifications
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
* @throws SOPGPException.NoSignature when no signature is found * @throws SOPGPException.NoSignature when no valid signature is found
* @throws SOPGPException.BadData when the data is invalid OpenPGP data * @throws SOPGPException.BadData when the data is invalid OpenPGP data
*/ */
List<Verification> data(InputStream data) throws IOException, SOPGPException.NoSignature, SOPGPException.BadData; List<Verification> data(InputStream data)
throws IOException,
SOPGPException.NoSignature,
SOPGPException.BadData;
/** /**
* Provide the signed data (without signatures). * Provide the signed data (without signatures).
@ -31,10 +34,13 @@ public interface VerifySignatures {
* @param data signed data * @param data signed data
* @return list of signature verifications * @return list of signature verifications
* @throws IOException in case of an IO error * @throws IOException in case of an IO error
* @throws SOPGPException.NoSignature when no signature is found * @throws SOPGPException.NoSignature when no valid signature is found
* @throws SOPGPException.BadData when the data is invalid OpenPGP data * @throws SOPGPException.BadData when the data is invalid OpenPGP data
*/ */
default List<Verification> data(byte[] data) throws IOException, SOPGPException.NoSignature, SOPGPException.BadData { default List<Verification> data(byte[] data)
throws IOException,
SOPGPException.NoSignature,
SOPGPException.BadData {
return data(new ByteArrayInputStream(data)); return data(new ByteArrayInputStream(data));
} }
} }