diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/ArmorImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/ArmorImpl.java index daee3a9b..421dc7a7 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/ArmorImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/ArmorImpl.java @@ -18,21 +18,26 @@ import sop.enums.ArmorLabel; import sop.exception.SOPGPException; import sop.operation.Armor; +import javax.annotation.Nonnull; + /** * Implementation of the
armor
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); diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/ChangeKeyPasswordImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/ChangeKeyPasswordImpl.java index 95377b12..56613720 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/ChangeKeyPasswordImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/ChangeKeyPasswordImpl.java @@ -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); diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/DearmorImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/DearmorImpl.java index 29483437..5fd0a03b 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/DearmorImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/DearmorImpl.java @@ -15,13 +15,16 @@ import sop.Ready; import sop.exception.SOPGPException; import sop.operation.Dearmor; +import javax.annotation.Nonnull; + /** * Implementation of the
dearmor
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(); diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/DecryptImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/DecryptImpl.java index d15713ca..bc5081d7 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/DecryptImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/DecryptImpl.java @@ -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
decrypt
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 ciphertext(InputStream ciphertext) + public ReadyWithResult ciphertext(@Nonnull InputStream ciphertext) throws SOPGPException.BadData, SOPGPException.MissingArg { @@ -136,7 +146,7 @@ public class DecryptImpl implements Decrypt { return new ReadyWithResult() { @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(); diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedSignImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedSignImpl.java index c32cb219..034e13bc 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedSignImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedSignImpl.java @@ -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
sign
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 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 data(InputStream data) throws IOException { + @Nonnull + public ReadyWithResult 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() { @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; } } diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedVerifyImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedVerifyImpl.java index cdae0215..4c475bd0 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedVerifyImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/DetachedVerifyImpl.java @@ -23,6 +23,8 @@ import sop.Verification; import sop.exception.SOPGPException; import sop.operation.DetachedVerify; +import javax.annotation.Nonnull; + /** * Implementation of the
verify
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 data(InputStream data) throws IOException, SOPGPException.NoSignature, SOPGPException.BadData { + @Nonnull + public List data(@Nonnull InputStream data) throws IOException, SOPGPException.NoSignature, SOPGPException.BadData { options.forceNonOpenPgpData(); DecryptionStream decryptionStream; diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/EncryptImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/EncryptImpl.java index 08c58395..cbd5a108 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/EncryptImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/EncryptImpl.java @@ -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
encrypt
operation using PGPainless. @@ -52,23 +55,26 @@ public class EncryptImpl implements Encrypt { private final Set 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 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() { @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); diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/ExtractCertImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/ExtractCertImpl.java index be7fc9c3..6dce2578 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/ExtractCertImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/ExtractCertImpl.java @@ -19,6 +19,8 @@ import sop.Ready; import sop.exception.SOPGPException; import sop.operation.ExtractCert; +import javax.annotation.Nonnull; + /** * Implementation of the
extract-cert
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 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; diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/GenerateKeyImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/GenerateKeyImpl.java index b6d5fe73..03583891 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/GenerateKeyImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/GenerateKeyImpl.java @@ -31,6 +31,8 @@ import sop.Ready; import sop.exception.SOPGPException; import sop.operation.GenerateKey; +import javax.annotation.Nonnull; + /** * Implementation of the
generate-key
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); diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineDetachImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineDetachImpl.java index da6e0917..85c06d25 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineDetachImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineDetachImpl.java @@ -30,6 +30,8 @@ import sop.Signatures; import sop.exception.SOPGPException; import sop.operation.InlineDetach; +import javax.annotation.Nonnull; + /** * Implementation of the
inline-detach
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 message(InputStream messageInputStream) { + @Nonnull + public ReadyWithResult message(@Nonnull InputStream messageInputStream) { return new ReadyWithResult() { 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); } }; diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineSignImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineSignImpl.java index dd4ab0cf..6ed1d471 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineSignImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineSignImpl.java @@ -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
inline-sign
operation using PGPainless. @@ -41,19 +43,22 @@ public class InlineSignImpl implements InlineSign { private final List 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) diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineVerifyImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineVerifyImpl.java index aecb891b..352bd7c8 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineVerifyImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/InlineVerifyImpl.java @@ -26,6 +26,8 @@ import sop.Verification; import sop.exception.SOPGPException; import sop.operation.InlineVerify; +import javax.annotation.Nonnull; + /** * Implementation of the
inline-verify
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> data(InputStream data) throws SOPGPException.NoSignature, SOPGPException.BadData { + @Nonnull + public ReadyWithResult> data(@Nonnull InputStream data) throws SOPGPException.NoSignature, SOPGPException.BadData { return new ReadyWithResult>() { @Override - public List writeTo(OutputStream outputStream) throws IOException, SOPGPException.NoSignature { + public List writeTo(@Nonnull OutputStream outputStream) throws IOException, SOPGPException.NoSignature { DecryptionStream decryptionStream; try { decryptionStream = PGPainless.decryptAndOrVerify() diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/ListProfilesImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/ListProfilesImpl.java index 36ef4861..e39c080d 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/ListProfilesImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/ListProfilesImpl.java @@ -10,6 +10,8 @@ import sop.Profile; import sop.exception.SOPGPException; import sop.operation.ListProfiles; +import javax.annotation.Nonnull; + /** * Implementation of the
list-profiles
operation using PGPainless. * @@ -17,10 +19,8 @@ import sop.operation.ListProfiles; public class ListProfilesImpl implements ListProfiles { @Override - public List subcommand(String command) { - if (command == null) { - throw new SOPGPException.UnsupportedProfile("null"); - } + @Nonnull + public List subcommand(@Nonnull String command) { switch (command) { case "generate-key": diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/RevokeKeyImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/RevokeKeyImpl.java index 6d72bf8f..6b11b73a 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/RevokeKeyImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/RevokeKeyImpl.java @@ -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); diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/SOPImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/SOPImpl.java index 4009d2a8..d13ebc02 100644 --- a/pgpainless-sop/src/main/java/org/pgpainless/sop/SOPImpl.java +++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/SOPImpl.java @@ -22,6 +22,8 @@ import sop.operation.ListProfiles; import sop.operation.RevokeKey; import sop.operation.Version; +import javax.annotation.Nonnull; + /** * Implementation of the
sop
API using PGPainless. *
 {@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();
     }
diff --git a/pgpainless-sop/src/main/java/org/pgpainless/sop/VersionImpl.java b/pgpainless-sop/src/main/java/org/pgpainless/sop/VersionImpl.java
index 488d95b3..424f8d19 100644
--- a/pgpainless-sop/src/main/java/org/pgpainless/sop/VersionImpl.java
+++ b/pgpainless-sop/src/main/java/org/pgpainless/sop/VersionImpl.java
@@ -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 
version
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);