Annotate methods with @Nonnull

This commit is contained in:
Paul Schaub 2023-11-15 13:39:26 +01:00
parent f07063d55f
commit 608ec0b7b0
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
16 changed files with 190 additions and 78 deletions

View File

@ -18,21 +18,26 @@ import sop.enums.ArmorLabel;
import sop.exception.SOPGPException;
import sop.operation.Armor;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>armor</pre> operation using PGPainless.
*/
public class ArmorImpl implements Armor {
@Nonnull
@Override
public Armor label(ArmorLabel label) throws SOPGPException.UnsupportedOption {
@Deprecated
public Armor label(@Nonnull ArmorLabel label) throws SOPGPException.UnsupportedOption {
throw new SOPGPException.UnsupportedOption("Setting custom Armor labels not supported.");
}
@Nonnull
@Override
public Ready data(InputStream data) throws SOPGPException.BadData {
public Ready data(@Nonnull InputStream data) throws SOPGPException.BadData {
return new Ready() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
public void writeTo(@Nonnull OutputStream outputStream) throws IOException {
// By buffering the output stream, we can improve performance drastically
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);

View File

@ -24,32 +24,38 @@ import sop.Ready;
import sop.exception.SOPGPException;
import sop.operation.ChangeKeyPassword;
import javax.annotation.Nonnull;
public class ChangeKeyPasswordImpl implements ChangeKeyPassword {
private final MatchMakingSecretKeyRingProtector oldProtector = new MatchMakingSecretKeyRingProtector();
private Passphrase newPassphrase = Passphrase.emptyPassphrase();
private boolean armor = true;
@Nonnull
@Override
public ChangeKeyPassword noArmor() {
armor = false;
return this;
}
@Nonnull
@Override
public ChangeKeyPassword oldKeyPassphrase(String oldPassphrase) {
public ChangeKeyPassword oldKeyPassphrase(@Nonnull String oldPassphrase) {
oldProtector.addPassphrase(Passphrase.fromPassword(oldPassphrase));
return this;
}
@Nonnull
@Override
public ChangeKeyPassword newKeyPassphrase(String newPassphrase) {
public ChangeKeyPassword newKeyPassphrase(@Nonnull String newPassphrase) {
this.newPassphrase = Passphrase.fromPassword(newPassphrase);
return this;
}
@Nonnull
@Override
public Ready keys(InputStream inputStream) throws SOPGPException.KeyIsProtected {
public Ready keys(@Nonnull InputStream inputStream) throws SOPGPException.KeyIsProtected {
SecretKeyRingProtector newProtector = SecretKeyRingProtector.unlockAnyKeyWith(newPassphrase);
PGPSecretKeyRingCollection secretKeyRingCollection;
try {
@ -76,7 +82,7 @@ public class ChangeKeyPasswordImpl implements ChangeKeyPassword {
final PGPSecretKeyRingCollection changedSecretKeyCollection = new PGPSecretKeyRingCollection(updatedSecretKeys);
return new Ready() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
public void writeTo(@Nonnull OutputStream outputStream) throws IOException {
if (armor) {
ArmoredOutputStream armorOut = ArmoredOutputStreamFactory.get(outputStream);
changedSecretKeyCollection.encode(armorOut);

View File

@ -15,13 +15,16 @@ import sop.Ready;
import sop.exception.SOPGPException;
import sop.operation.Dearmor;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>dearmor</pre> operation using PGPainless.
*/
public class DearmorImpl implements Dearmor {
@Nonnull
@Override
public Ready data(InputStream data) {
public Ready data(@Nonnull InputStream data) {
InputStream decoder;
try {
decoder = PGPUtil.getDecoderStream(data);
@ -31,7 +34,7 @@ public class DearmorImpl implements Dearmor {
return new Ready() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
public void writeTo(@Nonnull OutputStream outputStream) throws IOException {
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
Streams.pipeAll(decoder, bufferedOutputStream);
bufferedOutputStream.flush();

View File

@ -7,7 +7,6 @@ package org.pgpainless.sop;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -33,6 +32,9 @@ import sop.SessionKey;
import sop.Verification;
import sop.exception.SOPGPException;
import sop.operation.Decrypt;
import sop.util.UTF8Util;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>decrypt</pre> operation using PGPainless.
@ -42,20 +44,23 @@ public class DecryptImpl implements Decrypt {
private final ConsumerOptions consumerOptions = ConsumerOptions.get();
private final MatchMakingSecretKeyRingProtector protector = new MatchMakingSecretKeyRingProtector();
@Nonnull
@Override
public DecryptImpl verifyNotBefore(Date timestamp) throws SOPGPException.UnsupportedOption {
public DecryptImpl verifyNotBefore(@Nonnull Date timestamp) throws SOPGPException.UnsupportedOption {
consumerOptions.verifyNotBefore(timestamp);
return this;
}
@Nonnull
@Override
public DecryptImpl verifyNotAfter(Date timestamp) throws SOPGPException.UnsupportedOption {
public DecryptImpl verifyNotAfter(@Nonnull Date timestamp) throws SOPGPException.UnsupportedOption {
consumerOptions.verifyNotAfter(timestamp);
return this;
}
@Nonnull
@Override
public DecryptImpl verifyWithCert(InputStream certIn) throws SOPGPException.BadData, IOException {
public DecryptImpl verifyWithCert(@Nonnull InputStream certIn) throws SOPGPException.BadData, IOException {
PGPPublicKeyRingCollection certs = KeyReader.readPublicKeys(certIn, true);
if (certs != null) {
consumerOptions.addVerificationCerts(certs);
@ -63,8 +68,9 @@ public class DecryptImpl implements Decrypt {
return this;
}
@Nonnull
@Override
public DecryptImpl withSessionKey(SessionKey sessionKey) throws SOPGPException.UnsupportedOption {
public DecryptImpl withSessionKey(@Nonnull SessionKey sessionKey) throws SOPGPException.UnsupportedOption {
consumerOptions.setSessionKey(
new org.pgpainless.util.SessionKey(
SymmetricKeyAlgorithm.requireFromId(sessionKey.getAlgorithm()),
@ -72,8 +78,9 @@ public class DecryptImpl implements Decrypt {
return this;
}
@Nonnull
@Override
public DecryptImpl withPassword(String password) {
public DecryptImpl withPassword(@Nonnull String password) {
consumerOptions.addDecryptionPassphrase(Passphrase.fromPassword(password));
String withoutTrailingWhitespace = removeTrailingWhitespace(password);
if (!password.equals(withoutTrailingWhitespace)) {
@ -91,8 +98,9 @@ public class DecryptImpl implements Decrypt {
return passphrase.substring(0, i);
}
@Nonnull
@Override
public DecryptImpl withKey(InputStream keyIn) throws SOPGPException.BadData, IOException, SOPGPException.UnsupportedAsymmetricAlgo {
public DecryptImpl withKey(@Nonnull InputStream keyIn) throws SOPGPException.BadData, IOException, SOPGPException.UnsupportedAsymmetricAlgo {
PGPSecretKeyRingCollection secretKeyCollection = KeyReader.readSecretKeys(keyIn, true);
for (PGPSecretKeyRing key : secretKeyCollection) {
@ -102,15 +110,17 @@ public class DecryptImpl implements Decrypt {
return this;
}
@Nonnull
@Override
public Decrypt withKeyPassword(byte[] password) {
String string = new String(password, Charset.forName("UTF8"));
public Decrypt withKeyPassword(@Nonnull byte[] password) {
String string = new String(password, UTF8Util.UTF8);
protector.addPassphrase(Passphrase.fromPassword(string));
return this;
}
@Nonnull
@Override
public ReadyWithResult<DecryptionResult> ciphertext(InputStream ciphertext)
public ReadyWithResult<DecryptionResult> ciphertext(@Nonnull InputStream ciphertext)
throws SOPGPException.BadData,
SOPGPException.MissingArg {
@ -136,7 +146,7 @@ public class DecryptImpl implements Decrypt {
return new ReadyWithResult<DecryptionResult>() {
@Override
public DecryptionResult writeTo(OutputStream outputStream) throws IOException, SOPGPException.NoSignature {
public DecryptionResult writeTo(@Nonnull OutputStream outputStream) throws IOException, SOPGPException.NoSignature {
Streams.pipeAll(decryptionStream, outputStream);
decryptionStream.close();
MessageMetadata metadata = decryptionStream.getMetadata();

View File

@ -8,7 +8,6 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
@ -35,6 +34,9 @@ import sop.SigningResult;
import sop.enums.SignAs;
import sop.exception.SOPGPException;
import sop.operation.DetachedSign;
import sop.util.UTF8Util;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>sign</pre> operation using PGPainless.
@ -42,7 +44,7 @@ import sop.operation.DetachedSign;
public class DetachedSignImpl implements DetachedSign {
private boolean armor = true;
private SignAs mode = SignAs.Binary;
private SignAs mode = SignAs.binary;
private final SigningOptions signingOptions = SigningOptions.get();
private final MatchMakingSecretKeyRingProtector protector = new MatchMakingSecretKeyRingProtector();
private final List<PGPSecretKeyRing> signingKeys = new ArrayList<>();
@ -54,13 +56,15 @@ public class DetachedSignImpl implements DetachedSign {
}
@Override
public DetachedSign mode(SignAs mode) {
@Nonnull
public DetachedSign mode(@Nonnull SignAs mode) {
this.mode = mode;
return this;
}
@Override
public DetachedSign key(InputStream keyIn) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException {
@Nonnull
public DetachedSign key(@Nonnull InputStream keyIn) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException {
PGPSecretKeyRingCollection keys = KeyReader.readSecretKeys(keyIn, true);
for (PGPSecretKeyRing key : keys) {
KeyRingInfo info = PGPainless.inspectKeyRing(key);
@ -74,14 +78,16 @@ public class DetachedSignImpl implements DetachedSign {
}
@Override
public DetachedSign withKeyPassword(byte[] password) {
String string = new String(password, Charset.forName("UTF8"));
@Nonnull
public DetachedSign withKeyPassword(@Nonnull byte[] password) {
String string = new String(password, UTF8Util.UTF8);
protector.addPassphrase(Passphrase.fromPassword(string));
return this;
}
@Override
public ReadyWithResult<SigningResult> data(InputStream data) throws IOException {
@Nonnull
public ReadyWithResult<SigningResult> data(@Nonnull InputStream data) throws IOException {
for (PGPSecretKeyRing key : signingKeys) {
try {
signingOptions.addDetachedSignature(protector, key, modeToSigType(mode));
@ -101,7 +107,7 @@ public class DetachedSignImpl implements DetachedSign {
return new ReadyWithResult<SigningResult>() {
@Override
public SigningResult writeTo(OutputStream outputStream) throws IOException {
public SigningResult writeTo(@Nonnull OutputStream outputStream) throws IOException {
if (signingStream.isClosed()) {
throw new IllegalStateException("EncryptionStream is already closed.");
@ -157,7 +163,7 @@ public class DetachedSignImpl implements DetachedSign {
}
private static DocumentSignatureType modeToSigType(SignAs mode) {
return mode == SignAs.Binary ? DocumentSignatureType.BINARY_DOCUMENT
return mode == SignAs.binary ? DocumentSignatureType.BINARY_DOCUMENT
: DocumentSignatureType.CANONICAL_TEXT_DOCUMENT;
}
}

View File

@ -23,6 +23,8 @@ import sop.Verification;
import sop.exception.SOPGPException;
import sop.operation.DetachedVerify;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>verify</pre> operation using PGPainless.
*/
@ -31,26 +33,30 @@ public class DetachedVerifyImpl implements DetachedVerify {
private final ConsumerOptions options = ConsumerOptions.get();
@Override
public DetachedVerify notBefore(Date timestamp) throws SOPGPException.UnsupportedOption {
@Nonnull
public DetachedVerify notBefore(@Nonnull Date timestamp) throws SOPGPException.UnsupportedOption {
options.verifyNotBefore(timestamp);
return this;
}
@Override
public DetachedVerify notAfter(Date timestamp) throws SOPGPException.UnsupportedOption {
@Nonnull
public DetachedVerify notAfter(@Nonnull Date timestamp) throws SOPGPException.UnsupportedOption {
options.verifyNotAfter(timestamp);
return this;
}
@Override
public DetachedVerify cert(InputStream cert) throws SOPGPException.BadData, IOException {
@Nonnull
public DetachedVerify cert(@Nonnull InputStream cert) throws SOPGPException.BadData, IOException {
PGPPublicKeyRingCollection certificates = KeyReader.readPublicKeys(cert, true);
options.addVerificationCerts(certificates);
return this;
}
@Override
public DetachedVerifyImpl signatures(InputStream signatures) throws SOPGPException.BadData {
@Nonnull
public DetachedVerifyImpl signatures(@Nonnull InputStream signatures) throws SOPGPException.BadData {
try {
options.addVerificationOfDetachedSignatures(signatures);
} catch (IOException | PGPException e) {
@ -60,7 +66,8 @@ public class DetachedVerifyImpl implements DetachedVerify {
}
@Override
public List<Verification> data(InputStream data) throws IOException, SOPGPException.NoSignature, SOPGPException.BadData {
@Nonnull
public List<Verification> data(@Nonnull InputStream data) throws IOException, SOPGPException.NoSignature, SOPGPException.BadData {
options.forceNonOpenPgpData();
DecryptionStream decryptionStream;

View File

@ -7,7 +7,6 @@ package org.pgpainless.sop;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@ -30,12 +29,16 @@ import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.OpenPgpFingerprint;
import org.pgpainless.key.info.KeyRingInfo;
import org.pgpainless.util.Passphrase;
import sop.EncryptionResult;
import sop.Profile;
import sop.Ready;
import sop.ReadyWithResult;
import sop.enums.EncryptAs;
import sop.exception.SOPGPException;
import sop.operation.Encrypt;
import sop.util.ProxyOutputStream;
import sop.util.UTF8Util;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>encrypt</pre> operation using PGPainless.
@ -52,23 +55,26 @@ public class EncryptImpl implements Encrypt {
private final Set<PGPSecretKeyRing> signingKeys = new HashSet<>();
private String profile = RFC4880_PROFILE.getName(); // TODO: Use in future releases
private EncryptAs encryptAs = EncryptAs.Binary;
private EncryptAs encryptAs = EncryptAs.binary;
boolean armor = true;
@Nonnull
@Override
public Encrypt noArmor() {
armor = false;
return this;
}
@Nonnull
@Override
public Encrypt mode(EncryptAs mode) throws SOPGPException.UnsupportedOption {
public Encrypt mode(@Nonnull EncryptAs mode) throws SOPGPException.UnsupportedOption {
this.encryptAs = mode;
return this;
}
@Nonnull
@Override
public Encrypt signWith(InputStream keyIn)
public Encrypt signWith(@Nonnull InputStream keyIn)
throws SOPGPException.KeyCannotSign, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData, IOException {
if (signingOptions == null) {
signingOptions = SigningOptions.get();
@ -89,21 +95,24 @@ public class EncryptImpl implements Encrypt {
return this;
}
@Nonnull
@Override
public Encrypt withKeyPassword(byte[] password) {
String passphrase = new String(password, Charset.forName("UTF8"));
public Encrypt withKeyPassword(@Nonnull byte[] password) {
String passphrase = new String(password, UTF8Util.UTF8);
protector.addPassphrase(Passphrase.fromPassword(passphrase));
return this;
}
@Nonnull
@Override
public Encrypt withPassword(String password) throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
public Encrypt withPassword(@Nonnull String password) throws SOPGPException.PasswordNotHumanReadable, SOPGPException.UnsupportedOption {
encryptionOptions.addPassphrase(Passphrase.fromPassword(password));
return this;
}
@Nonnull
@Override
public Encrypt withCert(InputStream cert) throws SOPGPException.CertCannotEncrypt, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData {
public Encrypt withCert(@Nonnull InputStream cert) throws SOPGPException.CertCannotEncrypt, SOPGPException.UnsupportedAsymmetricAlgo, SOPGPException.BadData {
try {
PGPPublicKeyRingCollection certificates = KeyReader.readPublicKeys(cert, true);
encryptionOptions.addRecipients(certificates);
@ -115,8 +124,9 @@ public class EncryptImpl implements Encrypt {
return this;
}
@Nonnull
@Override
public Encrypt profile(String profileName) {
public Encrypt profile(@Nonnull String profileName) {
// sanitize profile name to make sure we only accept supported profiles
for (Profile profile : SUPPORTED_PROFILES) {
if (profile.getName().equals(profileName)) {
@ -130,8 +140,9 @@ public class EncryptImpl implements Encrypt {
throw new SOPGPException.UnsupportedProfile("encrypt", profileName);
}
@Nonnull
@Override
public Ready plaintext(InputStream plaintext) throws IOException {
public ReadyWithResult<sop.EncryptionResult> plaintext(@Nonnull InputStream plaintext) throws IOException {
if (!encryptionOptions.hasEncryptionMethod()) {
throw new SOPGPException.MissingArg("Missing encryption method.");
}
@ -146,7 +157,7 @@ public class EncryptImpl implements Encrypt {
signingOptions.addInlineSignature(
protector,
signingKey,
(encryptAs == EncryptAs.Binary ? DocumentSignatureType.BINARY_DOCUMENT : DocumentSignatureType.CANONICAL_TEXT_DOCUMENT)
(encryptAs == EncryptAs.binary ? DocumentSignatureType.BINARY_DOCUMENT : DocumentSignatureType.CANONICAL_TEXT_DOCUMENT)
);
} catch (KeyException.UnacceptableSigningKeyException e) {
throw new SOPGPException.KeyCannotSign();
@ -163,12 +174,14 @@ public class EncryptImpl implements Encrypt {
.onOutputStream(proxy)
.withOptions(producerOptions);
return new Ready() {
return new ReadyWithResult<EncryptionResult>() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
public EncryptionResult writeTo(@Nonnull OutputStream outputStream) throws IOException {
proxy.replaceOutputStream(outputStream);
Streams.pipeAll(plaintext, encryptionStream);
encryptionStream.close();
// TODO: Extract and emit SessionKey
return new EncryptionResult(null);
}
};
} catch (PGPException e) {
@ -178,9 +191,9 @@ public class EncryptImpl implements Encrypt {
private static StreamEncoding encryptAsToStreamEncoding(EncryptAs encryptAs) {
switch (encryptAs) {
case Binary:
case binary:
return StreamEncoding.BINARY;
case Text:
case text:
return StreamEncoding.UTF8;
}
throw new IllegalArgumentException("Invalid value encountered: " + encryptAs);

View File

@ -19,6 +19,8 @@ import sop.Ready;
import sop.exception.SOPGPException;
import sop.operation.ExtractCert;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>extract-cert</pre> operation using PGPainless.
*/
@ -27,13 +29,15 @@ public class ExtractCertImpl implements ExtractCert {
private boolean armor = true;
@Override
@Nonnull
public ExtractCert noArmor() {
armor = false;
return this;
}
@Override
public Ready key(InputStream keyInputStream) throws IOException, SOPGPException.BadData {
@Nonnull
public Ready key(@Nonnull InputStream keyInputStream) throws IOException, SOPGPException.BadData {
PGPSecretKeyRingCollection keys = KeyReader.readSecretKeys(keyInputStream, true);
List<PGPPublicKeyRing> certs = new ArrayList<>();
@ -44,7 +48,7 @@ public class ExtractCertImpl implements ExtractCert {
return new Ready() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
public void writeTo(@Nonnull OutputStream outputStream) throws IOException {
for (PGPPublicKeyRing cert : certs) {
OutputStream out = armor ? ArmorUtils.toAsciiArmoredStream(cert, outputStream) : outputStream;

View File

@ -31,6 +31,8 @@ import sop.Ready;
import sop.exception.SOPGPException;
import sop.operation.GenerateKey;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>generate-key</pre> operation using PGPainless.
*/
@ -48,25 +50,29 @@ public class GenerateKeyImpl implements GenerateKey {
private String profile = CURVE25519_PROFILE.getName();
@Override
@Nonnull
public GenerateKey noArmor() {
this.armor = false;
return this;
}
@Override
public GenerateKey userId(String userId) {
@Nonnull
public GenerateKey userId(@Nonnull String userId) {
this.userIds.add(userId);
return this;
}
@Override
public GenerateKey withKeyPassword(String password) {
@Nonnull
public GenerateKey withKeyPassword(@Nonnull String password) {
this.passphrase = Passphrase.fromPassword(password);
return this;
}
@Override
public GenerateKey profile(String profileName) {
@Nonnull
public GenerateKey profile(@Nonnull String profileName) {
// Sanitize the profile name to make sure we support the given profile
for (Profile profile : SUPPORTED_PROFILES) {
if (profile.getName().equals(profileName)) {
@ -81,18 +87,20 @@ public class GenerateKeyImpl implements GenerateKey {
}
@Override
@Nonnull
public GenerateKey signingOnly() {
signingOnly = true;
return this;
}
@Override
@Nonnull
public Ready generate() throws SOPGPException.MissingArg, SOPGPException.UnsupportedAsymmetricAlgo {
try {
final PGPSecretKeyRing key = generateKeyWithProfile(profile, userIds, passphrase, signingOnly);
return new Ready() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
public void writeTo(@Nonnull OutputStream outputStream) throws IOException {
if (armor) {
ArmoredOutputStream armoredOutputStream = ArmorUtils.toAsciiArmoredStream(key, outputStream);
key.encode(armoredOutputStream);

View File

@ -30,6 +30,8 @@ import sop.Signatures;
import sop.exception.SOPGPException;
import sop.operation.InlineDetach;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>inline-detach</pre> operation using PGPainless.
*/
@ -38,20 +40,22 @@ public class InlineDetachImpl implements InlineDetach {
private boolean armor = true;
@Override
@Nonnull
public InlineDetach noArmor() {
this.armor = false;
return this;
}
@Override
public ReadyWithResult<Signatures> message(InputStream messageInputStream) {
@Nonnull
public ReadyWithResult<Signatures> message(@Nonnull InputStream messageInputStream) {
return new ReadyWithResult<Signatures>() {
private final ByteArrayOutputStream sigOut = new ByteArrayOutputStream();
@Override
public Signatures writeTo(OutputStream messageOutputStream)
public Signatures writeTo(@Nonnull OutputStream messageOutputStream)
throws SOPGPException.NoSignature, IOException {
PGPSignatureList signatures = null;
@ -142,7 +146,7 @@ public class InlineDetachImpl implements InlineDetach {
return new Signatures() {
@Override
public void writeTo(OutputStream signatureOutputStream) throws IOException {
public void writeTo(@Nonnull OutputStream signatureOutputStream) throws IOException {
Streams.pipeAll(new ByteArrayInputStream(sigOut.toByteArray()), signatureOutputStream);
}
};

View File

@ -7,7 +7,6 @@ package org.pgpainless.sop;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
@ -28,6 +27,9 @@ import sop.Ready;
import sop.enums.InlineSignAs;
import sop.exception.SOPGPException;
import sop.operation.InlineSign;
import sop.util.UTF8Util;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>inline-sign</pre> operation using PGPainless.
@ -41,19 +43,22 @@ public class InlineSignImpl implements InlineSign {
private final List<PGPSecretKeyRing> signingKeys = new ArrayList<>();
@Override
public InlineSign mode(InlineSignAs mode) throws SOPGPException.UnsupportedOption {
@Nonnull
public InlineSign mode(@Nonnull InlineSignAs mode) throws SOPGPException.UnsupportedOption {
this.mode = mode;
return this;
}
@Override
@Nonnull
public InlineSign noArmor() {
this.armor = false;
return this;
}
@Override
public InlineSign key(InputStream keyIn) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException {
@Nonnull
public InlineSign key(@Nonnull InputStream keyIn) throws SOPGPException.KeyCannotSign, SOPGPException.BadData, IOException {
PGPSecretKeyRingCollection keys = KeyReader.readSecretKeys(keyIn, true);
for (PGPSecretKeyRing key : keys) {
KeyRingInfo info = PGPainless.inspectKeyRing(key);
@ -67,14 +72,16 @@ public class InlineSignImpl implements InlineSign {
}
@Override
public InlineSign withKeyPassword(byte[] password) {
String string = new String(password, Charset.forName("UTF8"));
@Nonnull
public InlineSign withKeyPassword(@Nonnull byte[] password) {
String string = new String(password, UTF8Util.UTF8);
protector.addPassphrase(Passphrase.fromPassword(string));
return this;
}
@Override
public Ready data(InputStream data) throws SOPGPException.KeyIsProtected, SOPGPException.ExpectedText {
@Nonnull
public Ready data(@Nonnull InputStream data) throws SOPGPException.KeyIsProtected, SOPGPException.ExpectedText {
for (PGPSecretKeyRing key : signingKeys) {
try {
if (mode == InlineSignAs.clearsigned) {
@ -99,7 +106,7 @@ public class InlineSignImpl implements InlineSign {
return new Ready() {
@Override
public void writeTo(OutputStream outputStream) throws IOException, SOPGPException.NoSignature {
public void writeTo(@Nonnull OutputStream outputStream) throws IOException, SOPGPException.NoSignature {
try {
EncryptionStream signingStream = PGPainless.encryptAndOrSign()
.onOutputStream(outputStream)

View File

@ -26,6 +26,8 @@ import sop.Verification;
import sop.exception.SOPGPException;
import sop.operation.InlineVerify;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>inline-verify</pre> operation using PGPainless.
*/
@ -34,29 +36,33 @@ public class InlineVerifyImpl implements InlineVerify {
private final ConsumerOptions options = ConsumerOptions.get();
@Override
public InlineVerify notBefore(Date timestamp) throws SOPGPException.UnsupportedOption {
@Nonnull
public InlineVerify notBefore(@Nonnull Date timestamp) throws SOPGPException.UnsupportedOption {
options.verifyNotBefore(timestamp);
return this;
}
@Override
public InlineVerify notAfter(Date timestamp) throws SOPGPException.UnsupportedOption {
@Nonnull
public InlineVerify notAfter(@Nonnull Date timestamp) throws SOPGPException.UnsupportedOption {
options.verifyNotAfter(timestamp);
return this;
}
@Override
public InlineVerify cert(InputStream cert) throws SOPGPException.BadData, IOException {
@Nonnull
public InlineVerify cert(@Nonnull InputStream cert) throws SOPGPException.BadData, IOException {
PGPPublicKeyRingCollection certificates = KeyReader.readPublicKeys(cert, true);
options.addVerificationCerts(certificates);
return this;
}
@Override
public ReadyWithResult<List<Verification>> data(InputStream data) throws SOPGPException.NoSignature, SOPGPException.BadData {
@Nonnull
public ReadyWithResult<List<Verification>> data(@Nonnull InputStream data) throws SOPGPException.NoSignature, SOPGPException.BadData {
return new ReadyWithResult<List<Verification>>() {
@Override
public List<Verification> writeTo(OutputStream outputStream) throws IOException, SOPGPException.NoSignature {
public List<Verification> writeTo(@Nonnull OutputStream outputStream) throws IOException, SOPGPException.NoSignature {
DecryptionStream decryptionStream;
try {
decryptionStream = PGPainless.decryptAndOrVerify()

View File

@ -10,6 +10,8 @@ import sop.Profile;
import sop.exception.SOPGPException;
import sop.operation.ListProfiles;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>list-profiles</pre> operation using PGPainless.
*
@ -17,10 +19,8 @@ import sop.operation.ListProfiles;
public class ListProfilesImpl implements ListProfiles {
@Override
public List<Profile> subcommand(String command) {
if (command == null) {
throw new SOPGPException.UnsupportedProfile("null");
}
@Nonnull
public List<Profile> subcommand(@Nonnull String command) {
switch (command) {
case "generate-key":

View File

@ -32,11 +32,15 @@ import sop.exception.SOPGPException;
import sop.operation.RevokeKey;
import sop.util.UTF8Util;
import javax.annotation.Nonnull;
public class RevokeKeyImpl implements RevokeKey {
private final MatchMakingSecretKeyRingProtector protector = new MatchMakingSecretKeyRingProtector();
private boolean armor = true;
@Override
@Nonnull
public RevokeKey noArmor() {
this.armor = false;
return this;
@ -50,7 +54,9 @@ public class RevokeKeyImpl implements RevokeKey {
* @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
*/
public RevokeKey withKeyPassword(byte[] password)
@Override
@Nonnull
public RevokeKey withKeyPassword(@Nonnull byte[] password)
throws SOPGPException.UnsupportedOption,
SOPGPException.PasswordNotHumanReadable {
String string;
@ -63,7 +69,9 @@ public class RevokeKeyImpl implements RevokeKey {
return this;
}
public Ready keys(InputStream keys) throws SOPGPException.BadData {
@Override
@Nonnull
public Ready keys(@Nonnull InputStream keys) throws SOPGPException.BadData {
PGPSecretKeyRingCollection secretKeyRings;
try {
secretKeyRings = KeyReader.readSecretKeys(keys, true);
@ -100,7 +108,7 @@ public class RevokeKeyImpl implements RevokeKey {
return new Ready() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
public void writeTo(@Nonnull OutputStream outputStream) throws IOException {
PGPPublicKeyRingCollection certificateCollection = new PGPPublicKeyRingCollection(revocationCertificates);
if (armor) {
ArmoredOutputStream out = ArmoredOutputStreamFactory.get(outputStream);

View File

@ -22,6 +22,8 @@ import sop.operation.ListProfiles;
import sop.operation.RevokeKey;
import sop.operation.Version;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>sop</pre> API using PGPainless.
* <pre> {@code
@ -35,86 +37,103 @@ public class SOPImpl implements SOP {
}
@Override
@Nonnull
public Version version() {
return new VersionImpl();
}
@Override
@Nonnull
public GenerateKey generateKey() {
return new GenerateKeyImpl();
}
@Override
@Nonnull
public ExtractCert extractCert() {
return new ExtractCertImpl();
}
@Override
@Nonnull
public DetachedSign sign() {
return detachedSign();
}
@Override
@Nonnull
public DetachedSign detachedSign() {
return new DetachedSignImpl();
}
@Override
@Nonnull
public InlineSign inlineSign() {
return new InlineSignImpl();
}
@Override
@Nonnull
public DetachedVerify verify() {
return detachedVerify();
}
@Override
@Nonnull
public DetachedVerify detachedVerify() {
return new DetachedVerifyImpl();
}
@Override
@Nonnull
public InlineVerify inlineVerify() {
return new InlineVerifyImpl();
}
@Override
@Nonnull
public Encrypt encrypt() {
return new EncryptImpl();
}
@Override
@Nonnull
public Decrypt decrypt() {
return new DecryptImpl();
}
@Override
@Nonnull
public Armor armor() {
return new ArmorImpl();
}
@Override
@Nonnull
public Dearmor dearmor() {
return new DearmorImpl();
}
@Override
@Nonnull
public ListProfiles listProfiles() {
return new ListProfilesImpl();
}
@Override
@Nonnull
public RevokeKey revokeKey() {
return new RevokeKeyImpl();
}
@Override
@Nonnull
public ChangeKeyPassword changeKeyPassword() {
return new ChangeKeyPasswordImpl();
}
@Override
@Nonnull
public InlineDetach inlineDetach() {
return new InlineDetachImpl();
}

View File

@ -12,6 +12,8 @@ import java.util.Properties;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sop.operation.Version;
import javax.annotation.Nonnull;
/**
* Implementation of the <pre>version</pre> operation using PGPainless.
*/
@ -21,11 +23,13 @@ public class VersionImpl implements Version {
private static final int SOP_VERSION = 7;
@Override
@Nonnull
public String getName() {
return "PGPainless-SOP";
}
@Override
@Nonnull
public String getVersion() {
// See https://stackoverflow.com/a/50119235
String version;
@ -44,11 +48,13 @@ public class VersionImpl implements Version {
}
@Override
@Nonnull
public String getBackendVersion() {
return "PGPainless " + getVersion();
}
@Override
@Nonnull
public String getExtendedVersion() {
double bcVersion = new BouncyCastleProvider().getVersion();
String FORMAT_VERSION = String.format("%02d", SOP_VERSION);