Add @Nullable, @Nonnull annotations through findbugs

This commit is contained in:
Paul Schaub 2018-07-31 20:09:16 +02:00
parent 51991bdb07
commit b89d3562ac
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
53 changed files with 387 additions and 370 deletions

View File

@ -7,4 +7,7 @@ dependencies {
compile 'org.bouncycastle:bcprov-jdk15on:1.60'
//*/
compile 'org.bouncycastle:bcpg-jdk15on:1.60'
// https://mvnrepository.com/artifact/com.google.code.findbugs/jsr305
compile group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2'
}

View File

@ -15,6 +15,9 @@
*/
package org.pgpainless;
import javax.annotation.Nonnull;
import java.io.IOException;
import org.bouncycastle.openpgp.PGPException;
import org.pgpainless.algorithm.CompressionAlgorithm;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
@ -27,8 +30,6 @@ import org.pgpainless.key.parsing.KeyRingReader;
import org.pgpainless.symmetric_encryption.SymmetricEncryptorDecryptor;
import org.pgpainless.util.Passphrase;
import java.io.IOException;
public class PGPainless {
/**
@ -73,7 +74,7 @@ public class PGPainless {
* @throws IOException IO is dangerous.
* @throws PGPException PGP is brittle.
*/
public static byte[] encryptWithPassword(byte[] data, Passphrase password, SymmetricKeyAlgorithm algorithm) throws IOException, PGPException {
public static byte[] encryptWithPassword(@Nonnull byte[] data, @Nonnull Passphrase password, @Nonnull SymmetricKeyAlgorithm algorithm) throws IOException, PGPException {
return SymmetricEncryptorDecryptor.symmetricallyEncrypt(data, password,
algorithm, CompressionAlgorithm.UNCOMPRESSED);
}
@ -88,7 +89,7 @@ public class PGPainless {
* @throws IOException IO is dangerous.
* @throws PGPException PGP is brittle.
*/
public static byte[] decryptWithPassword(byte[] data, Passphrase password) throws IOException, PGPException {
public static byte[] decryptWithPassword(@Nonnull byte[] data, @Nonnull Passphrase password) throws IOException, PGPException {
return SymmetricEncryptorDecryptor.symmetricallyDecrypt(data, password);
}
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.decryption_verification;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
@ -45,7 +46,7 @@ public class DecryptionBuilder implements DecryptionBuilderInterface {
class DecryptWithImpl implements DecryptWith {
@Override
public VerifyWith decryptWith(SecretKeyRingProtector decryptor, PGPSecretKeyRingCollection secretKeyRings) {
public VerifyWith decryptWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRingCollection secretKeyRings) {
DecryptionBuilder.this.decryptionKeys = secretKeyRings;
DecryptionBuilder.this.decryptionKeyDecryptor = decryptor;
return new VerifyWithImpl();
@ -62,7 +63,7 @@ public class DecryptionBuilder implements DecryptionBuilderInterface {
class VerifyWithImpl implements VerifyWith {
@Override
public HandleMissingPublicKeys verifyWith(PGPPublicKeyRingCollection publicKeyRingCollection) {
public HandleMissingPublicKeys verifyWith(@Nonnull PGPPublicKeyRingCollection publicKeyRingCollection) {
Set<PGPPublicKeyRing> publicKeyRings = new HashSet<>();
for (Iterator<PGPPublicKeyRing> i = publicKeyRingCollection.getKeyRings(); i.hasNext(); ) {
publicKeyRings.add(i.next());
@ -71,8 +72,8 @@ public class DecryptionBuilder implements DecryptionBuilderInterface {
}
@Override
public HandleMissingPublicKeys verifyWith(Set<OpenPgpV4Fingerprint> trustedKeyIds,
PGPPublicKeyRingCollection publicKeyRingCollection) {
public HandleMissingPublicKeys verifyWith(@Nonnull Set<OpenPgpV4Fingerprint> trustedKeyIds,
@Nonnull PGPPublicKeyRingCollection publicKeyRingCollection) {
Set<PGPPublicKeyRing> publicKeyRings = new HashSet<>();
for (Iterator<PGPPublicKeyRing> i = publicKeyRingCollection.getKeyRings(); i.hasNext(); ) {
PGPPublicKeyRing p = i.next();
@ -85,7 +86,7 @@ public class DecryptionBuilder implements DecryptionBuilderInterface {
}
@Override
public HandleMissingPublicKeys verifyWith(Set<PGPPublicKeyRing> publicKeyRings) {
public HandleMissingPublicKeys verifyWith(@Nonnull Set<PGPPublicKeyRing> publicKeyRings) {
DecryptionBuilder.this.verificationKeys = publicKeyRings;
return new HandleMissingPublicKeysImpl();
}
@ -100,7 +101,7 @@ public class DecryptionBuilder implements DecryptionBuilderInterface {
class HandleMissingPublicKeysImpl implements HandleMissingPublicKeys {
@Override
public Build handleMissingPublicKeysWith(MissingPublicKeyCallback callback) {
public Build handleMissingPublicKeysWith(@Nonnull MissingPublicKeyCallback callback) {
DecryptionBuilder.this.missingPublicKeyCallback = callback;
return new BuildImpl();
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.decryption_verification;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.InputStream;
import java.util.Set;
@ -32,7 +33,7 @@ public interface DecryptionBuilderInterface {
interface DecryptWith {
VerifyWith decryptWith(SecretKeyRingProtector decryptor, PGPSecretKeyRingCollection secretKeyRings);
VerifyWith decryptWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRingCollection secretKeyRings);
VerifyWith doNotDecrypt();
@ -40,11 +41,11 @@ public interface DecryptionBuilderInterface {
interface VerifyWith {
HandleMissingPublicKeys verifyWith(PGPPublicKeyRingCollection publicKeyRings);
HandleMissingPublicKeys verifyWith(@Nonnull PGPPublicKeyRingCollection publicKeyRings);
HandleMissingPublicKeys verifyWith(Set<OpenPgpV4Fingerprint> trustedFingerprints, PGPPublicKeyRingCollection publicKeyRings);
HandleMissingPublicKeys verifyWith(@Nonnull Set<OpenPgpV4Fingerprint> trustedFingerprints, @Nonnull PGPPublicKeyRingCollection publicKeyRings);
HandleMissingPublicKeys verifyWith(Set<PGPPublicKeyRing> publicKeyRings);
HandleMissingPublicKeys verifyWith(@Nonnull Set<PGPPublicKeyRing> publicKeyRings);
Build doNotVerify();
@ -52,7 +53,7 @@ public interface DecryptionBuilderInterface {
interface HandleMissingPublicKeys {
Build handleMissingPublicKeysWith(MissingPublicKeyCallback callback);
Build handleMissingPublicKeysWith(@Nonnull MissingPublicKeyCallback callback);
Build ignoreMissingPublicKeys();
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.decryption_verification;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.InputStream;
@ -24,12 +25,7 @@ public class DecryptionStream extends InputStream {
private final OpenPgpMetadata.Builder resultBuilder;
private boolean isClosed = false;
DecryptionStream(InputStream wrapped, OpenPgpMetadata.Builder resultBuilder) {
if (wrapped == null) {
throw new NullPointerException("Wrapped InputStream MUST NOT be null!");
}
DecryptionStream(@Nonnull InputStream wrapped, @Nonnull OpenPgpMetadata.Builder resultBuilder) {
this.inputStream = wrapped;
this.resultBuilder = resultBuilder;
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.decryption_verification;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
@ -66,21 +68,21 @@ public final class DecryptionStreamFactory {
private final KeyFingerPrintCalculator fingerCalc = new BcKeyFingerprintCalculator();
private final Map<OpenPgpV4Fingerprint, PGPOnePassSignature> verifiableOnePassSignatures = new HashMap<>();
private DecryptionStreamFactory(PGPSecretKeyRingCollection decryptionKeys,
SecretKeyRingProtector decryptor,
Set<PGPPublicKeyRing> verificationKeys,
MissingPublicKeyCallback missingPublicKeyCallback) {
private DecryptionStreamFactory(@Nullable PGPSecretKeyRingCollection decryptionKeys,
@Nullable SecretKeyRingProtector decryptor,
@Nullable Set<PGPPublicKeyRing> verificationKeys,
@Nullable MissingPublicKeyCallback missingPublicKeyCallback) {
this.decryptionKeys = decryptionKeys;
this.decryptionKeyDecryptor = decryptor;
this.verificationKeys.addAll(verificationKeys != null ? verificationKeys : Collections.emptyList());
this.missingPublicKeyCallback = missingPublicKeyCallback;
}
public static DecryptionStream create(InputStream inputStream,
PGPSecretKeyRingCollection decryptionKeys,
SecretKeyRingProtector decryptor,
Set<PGPPublicKeyRing> verificationKeys,
MissingPublicKeyCallback missingPublicKeyCallback)
public static DecryptionStream create(@Nonnull InputStream inputStream,
@Nullable PGPSecretKeyRingCollection decryptionKeys,
@Nullable SecretKeyRingProtector decryptor,
@Nullable Set<PGPPublicKeyRing> verificationKeys,
@Nullable MissingPublicKeyCallback missingPublicKeyCallback)
throws IOException, PGPException {
DecryptionStreamFactory factory = new DecryptionStreamFactory(decryptionKeys,
@ -94,7 +96,7 @@ public final class DecryptionStreamFactory {
return new DecryptionStream(factory.wrap(objectFactory), factory.resultBuilder);
}
private InputStream wrap(PGPObjectFactory objectFactory) throws IOException, PGPException {
private InputStream wrap(@Nonnull PGPObjectFactory objectFactory) throws IOException, PGPException {
Object pgpObj;
while ((pgpObj = objectFactory.nextObject()) != null) {
@ -142,7 +144,7 @@ public final class DecryptionStreamFactory {
throw new PGPException("No Literal Data Packet found");
}
private InputStream decrypt(PGPEncryptedDataList encryptedDataList)
private InputStream decrypt(@Nonnull PGPEncryptedDataList encryptedDataList)
throws PGPException {
Iterator<?> iterator = encryptedDataList.getEncryptedDataObjects();
if (!iterator.hasNext()) {
@ -190,7 +192,7 @@ public final class DecryptionStreamFactory {
return decryptionStream;
}
private void initOnePassSignatures(PGPOnePassSignatureList onePassSignatureList) throws PGPException {
private void initOnePassSignatures(@Nonnull PGPOnePassSignatureList onePassSignatureList) throws PGPException {
Iterator<PGPOnePassSignature> iterator = onePassSignatureList.iterator();
if (!iterator.hasNext()) {
throw new PGPException("Verification failed - No OnePassSignatures found");

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.decryption_verification;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPPublicKey;
public interface MissingPublicKeyCallback {
@ -29,6 +31,6 @@ public interface MissingPublicKeyCallback {
*
* @return the key or null
*/
PGPPublicKey onMissingPublicKeyEncountered(Long keyId);
PGPPublicKey onMissingPublicKeyEncountered(@Nonnull Long keyId);
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.decryption_verification;
import javax.annotation.Nonnull;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
@ -41,10 +42,10 @@ public class SignatureVerifyingInputStream extends FilterInputStream {
private boolean validated = false;
protected SignatureVerifyingInputStream(InputStream inputStream,
PGPObjectFactory objectFactory,
Map<OpenPgpV4Fingerprint, PGPOnePassSignature> onePassSignatures,
OpenPgpMetadata.Builder resultBuilder) {
protected SignatureVerifyingInputStream(@Nonnull InputStream inputStream,
@Nonnull PGPObjectFactory objectFactory,
@Nonnull Map<OpenPgpV4Fingerprint, PGPOnePassSignature> onePassSignatures,
@Nonnull OpenPgpMetadata.Builder resultBuilder) {
super(inputStream);
this.objectFactory = objectFactory;
this.resultBuilder = resultBuilder;

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.encryption_signing;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
@ -55,7 +56,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
private boolean asciiArmor = false;
@Override
public ToRecipients onOutputStream(OutputStream outputStream) {
public ToRecipients onOutputStream(@Nonnull OutputStream outputStream) {
this.outputStream = outputStream;
return new ToRecipientsImpl();
}
@ -63,7 +64,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
class ToRecipientsImpl implements ToRecipients {
@Override
public WithAlgorithms toRecipients(PGPPublicKey... keys) {
public WithAlgorithms toRecipients(@Nonnull PGPPublicKey... keys) {
for (PGPPublicKey k : keys) {
if (encryptionKeySelector().accept(null, k)) {
EncryptionBuilder.this.encryptionKeys.add(k);
@ -80,7 +81,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
}
@Override
public WithAlgorithms toRecipients(PGPPublicKeyRing... keys) {
public WithAlgorithms toRecipients(@Nonnull PGPPublicKeyRing... keys) {
for (PGPPublicKeyRing ring : keys) {
for (PGPPublicKey k : ring) {
if (encryptionKeySelector().accept(null, k)) {
@ -97,7 +98,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
}
@Override
public WithAlgorithms toRecipients(PGPPublicKeyRingCollection... keys) {
public WithAlgorithms toRecipients(@Nonnull PGPPublicKeyRingCollection... keys) {
for (PGPPublicKeyRingCollection collection : keys) {
for (PGPPublicKeyRing ring : collection) {
for (PGPPublicKey k : ring) {
@ -116,8 +117,8 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
}
@Override
public <O> WithAlgorithms toRecipients(PublicKeyRingSelectionStrategy<O> ringSelectionStrategy,
MultiMap<O, PGPPublicKeyRingCollection> keys) {
public <O> WithAlgorithms toRecipients(@Nonnull PublicKeyRingSelectionStrategy<O> ringSelectionStrategy,
@Nonnull MultiMap<O, PGPPublicKeyRingCollection> keys) {
if (keys.isEmpty()) {
throw new IllegalArgumentException("Recipient map MUST NOT be empty.");
}
@ -149,7 +150,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
class WithAlgorithmsImpl implements WithAlgorithms {
@Override
public WithAlgorithms andToSelf(PGPPublicKey... keys) {
public WithAlgorithms andToSelf(@Nonnull PGPPublicKey... keys) {
if (keys.length == 0) {
throw new IllegalArgumentException("Recipient list MUST NOT be empty.");
}
@ -164,7 +165,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
}
@Override
public WithAlgorithms andToSelf(PGPPublicKeyRing... keys) {
public WithAlgorithms andToSelf(@Nonnull PGPPublicKeyRing... keys) {
if (keys.length == 0) {
throw new IllegalArgumentException("Recipient list MUST NOT be empty.");
}
@ -180,7 +181,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
}
@Override
public WithAlgorithms andToSelf(PGPPublicKeyRingCollection keys) {
public WithAlgorithms andToSelf(@Nonnull PGPPublicKeyRingCollection keys) {
for (PGPPublicKeyRing ring : keys) {
for (Iterator<PGPPublicKey> i = ring.getPublicKeys(); i.hasNext(); ) {
PGPPublicKey key = i.next();
@ -192,8 +193,8 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
return this;
}
public <O> WithAlgorithms andToSelf(PublicKeyRingSelectionStrategy<O> ringSelectionStrategy,
MultiMap<O, PGPPublicKeyRingCollection> keys) {
public <O> WithAlgorithms andToSelf(@Nonnull PublicKeyRingSelectionStrategy<O> ringSelectionStrategy,
@Nonnull MultiMap<O, PGPPublicKeyRingCollection> keys) {
if (keys.isEmpty()) {
throw new IllegalArgumentException("Recipient list MUST NOT be empty.");
}
@ -214,9 +215,9 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
}
@Override
public SignWith usingAlgorithms(SymmetricKeyAlgorithm symmetricKeyAlgorithm,
HashAlgorithm hashAlgorithm,
CompressionAlgorithm compressionAlgorithm) {
public SignWith usingAlgorithms(@Nonnull SymmetricKeyAlgorithm symmetricKeyAlgorithm,
@Nonnull HashAlgorithm hashAlgorithm,
@Nonnull CompressionAlgorithm compressionAlgorithm) {
EncryptionBuilder.this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
EncryptionBuilder.this.hashAlgorithm = hashAlgorithm;
@ -238,7 +239,8 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
class SignWithImpl implements SignWith {
@Override
public <O> Armor signWith(SecretKeyRingProtector decryptor, PGPSecretKey... keys) {
public <O> Armor signWith(@Nonnull SecretKeyRingProtector decryptor,
@Nonnull PGPSecretKey... keys) {
if (keys.length == 0) {
throw new IllegalArgumentException("Recipient list MUST NOT be empty.");
}
@ -254,7 +256,8 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
}
@Override
public <O> Armor signWith(SecretKeyRingProtector decryptor, PGPSecretKeyRing... keys) {
public <O> Armor signWith(@Nonnull SecretKeyRingProtector decryptor,
@Nonnull PGPSecretKeyRing... keys) {
if (keys.length == 0) {
throw new IllegalArgumentException("Recipient list MUST NOT be empty.");
}
@ -271,9 +274,9 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
}
@Override
public <O> Armor signWith(SecretKeyRingSelectionStrategy<O> ringSelectionStrategy,
SecretKeyRingProtector decryptor,
MultiMap<O, PGPSecretKeyRingCollection> keys) {
public <O> Armor signWith(@Nonnull SecretKeyRingSelectionStrategy<O> ringSelectionStrategy,
@Nonnull SecretKeyRingProtector decryptor,
@Nonnull MultiMap<O, PGPSecretKeyRingCollection> keys) {
if (keys.isEmpty()) {
throw new IllegalArgumentException("Recipient list MUST NOT be empty.");
}
@ -320,7 +323,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
privateKeys.add(secretKey.extractPrivateKey(signingKeysDecryptor.getDecryptor(secretKey.getKeyID())));
}
return EncryptionStream.create(
return new EncryptionStream(
EncryptionBuilder.this.outputStream,
EncryptionBuilder.this.encryptionKeys,
privateKeys,

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.encryption_signing;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.OutputStream;
@ -36,18 +37,18 @@ import org.pgpainless.util.MultiMap;
public interface EncryptionBuilderInterface {
ToRecipients onOutputStream(OutputStream outputStream);
ToRecipients onOutputStream(@Nonnull OutputStream outputStream);
interface ToRecipients {
WithAlgorithms toRecipients(PGPPublicKey... keys);
WithAlgorithms toRecipients(@Nonnull PGPPublicKey... keys);
WithAlgorithms toRecipients(PGPPublicKeyRing... keys);
WithAlgorithms toRecipients(@Nonnull PGPPublicKeyRing... keys);
WithAlgorithms toRecipients(PGPPublicKeyRingCollection... keys);
WithAlgorithms toRecipients(@Nonnull PGPPublicKeyRingCollection... keys);
<O> WithAlgorithms toRecipients(PublicKeyRingSelectionStrategy<O> selectionStrategy,
MultiMap<O, PGPPublicKeyRingCollection> keys);
<O> WithAlgorithms toRecipients(@Nonnull PublicKeyRingSelectionStrategy<O> selectionStrategy,
@Nonnull MultiMap<O, PGPPublicKeyRingCollection> keys);
SignWith doNotEncrypt();
@ -55,18 +56,18 @@ public interface EncryptionBuilderInterface {
interface WithAlgorithms {
WithAlgorithms andToSelf(PGPPublicKey... keys);
WithAlgorithms andToSelf(@Nonnull PGPPublicKey... keys);
WithAlgorithms andToSelf(PGPPublicKeyRing... keys);
WithAlgorithms andToSelf(@Nonnull PGPPublicKeyRing... keys);
WithAlgorithms andToSelf(PGPPublicKeyRingCollection keys);
WithAlgorithms andToSelf(@Nonnull PGPPublicKeyRingCollection keys);
<O> WithAlgorithms andToSelf(PublicKeyRingSelectionStrategy<O> selectionStrategy,
MultiMap<O, PGPPublicKeyRingCollection> keys);
<O> WithAlgorithms andToSelf(@Nonnull PublicKeyRingSelectionStrategy<O> selectionStrategy,
@Nonnull MultiMap<O, PGPPublicKeyRingCollection> keys);
SignWith usingAlgorithms(SymmetricKeyAlgorithm symmetricKeyAlgorithm,
HashAlgorithm hashAlgorithm,
CompressionAlgorithm compressionAlgorithm);
SignWith usingAlgorithms(@Nonnull SymmetricKeyAlgorithm symmetricKeyAlgorithm,
@Nonnull HashAlgorithm hashAlgorithm,
@Nonnull CompressionAlgorithm compressionAlgorithm);
SignWith usingSecureAlgorithms();
@ -74,13 +75,13 @@ public interface EncryptionBuilderInterface {
interface SignWith {
<O> Armor signWith(SecretKeyRingProtector decryptor, PGPSecretKey... keys);
<O> Armor signWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKey... keys);
<O> Armor signWith(SecretKeyRingProtector decryptor, PGPSecretKeyRing... keyRings);
<O> Armor signWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRing... keyRings);
<O> Armor signWith(SecretKeyRingSelectionStrategy<O> selectionStrategy,
SecretKeyRingProtector decryptor,
MultiMap<O, PGPSecretKeyRingCollection> keys)
<O> Armor signWith(@Nonnull SecretKeyRingSelectionStrategy<O> selectionStrategy,
@Nonnull SecretKeyRingProtector decryptor,
@Nonnull MultiMap<O, PGPSecretKeyRingCollection> keys)
throws SecretKeyNotFoundException;
Armor doNotSign();

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.encryption_signing;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
@ -75,13 +76,13 @@ public final class EncryptionStream extends OutputStream {
private PGPLiteralDataGenerator literalDataGenerator;
private OutputStream literalDataStream;
private EncryptionStream(OutputStream targetOutputStream,
Set<PGPPublicKey> encryptionKeys,
Set<PGPPrivateKey> signingKeys,
SymmetricKeyAlgorithm symmetricKeyAlgorithm,
HashAlgorithm hashAlgorithm,
CompressionAlgorithm compressionAlgorithm,
boolean asciiArmor)
EncryptionStream(@Nonnull OutputStream targetOutputStream,
@Nonnull Set<PGPPublicKey> encryptionKeys,
@Nonnull Set<PGPPrivateKey> signingKeys,
@Nonnull SymmetricKeyAlgorithm symmetricKeyAlgorithm,
@Nonnull HashAlgorithm hashAlgorithm,
@Nonnull CompressionAlgorithm compressionAlgorithm,
boolean asciiArmor)
throws IOException, PGPException {
// Currently outermost Stream
@ -163,31 +164,6 @@ public final class EncryptionStream extends OutputStream {
signingKeyIds, Collections.emptySet());
}
static EncryptionStream create(OutputStream outputStream,
Set<PGPPublicKey> encryptionKeys,
Set<PGPPrivateKey> signingKeys,
SymmetricKeyAlgorithm symmetricKeyAlgorithm,
HashAlgorithm hashAlgorithm,
CompressionAlgorithm compressionAlgorithm,
boolean asciiArmor)
throws IOException, PGPException {
requireNonNull(outputStream, "targetOutputStream");
requireNonNull(encryptionKeys, "encryptionKeys");
requireNonNull(signingKeys, "signingKeys");
requireNonNull(symmetricKeyAlgorithm, "symmetricKeyAlgorithm");
requireNonNull(hashAlgorithm, "hashAlgorithm");
requireNonNull(compressionAlgorithm, "compressionAlgorithm");
return new EncryptionStream(outputStream,
encryptionKeys,
signingKeys,
symmetricKeyAlgorithm,
hashAlgorithm,
compressionAlgorithm,
asciiArmor);
}
@Override
public void write(int data) throws IOException {
literalDataStream.write(data);
@ -253,12 +229,6 @@ public final class EncryptionStream extends OutputStream {
}
}
private static void requireNonNull(Object o, String name) {
if (o == null) {
throw new IllegalArgumentException("Argument '" + name + "' MUST NOT be null.");
}
}
public OpenPgpMetadata getResult() {
return result;
}

View File

@ -1,38 +0,0 @@
/*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pgpainless.exception;
import org.bouncycastle.openpgp.PGPException;
public class PublicKeyNotFoundException extends Exception {
private static final long serialVersionUID = 1L;
private long keyId;
public PublicKeyNotFoundException(long keyId) {
super("No PGPPublicKey with id " + Long.toHexString(keyId) + " (" + keyId + ") found.");
this.keyId = keyId;
}
public PublicKeyNotFoundException(PGPException e) {
}
public long getKeyId() {
return keyId;
}
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key;
import javax.annotation.Nonnull;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
@ -39,10 +40,7 @@ public class OpenPgpV4Fingerprint implements CharSequence, Comparable<OpenPgpV4F
* XEP-0373 §4.1: The OpenPGP Public-Key Data Node about how to obtain the fingerprint</a>
* @param fingerprint hexadecimal representation of the fingerprint.
*/
public OpenPgpV4Fingerprint(String fingerprint) {
if (fingerprint == null) {
throw new NullPointerException("Fingerprint MUST NOT be null.");
}
public OpenPgpV4Fingerprint(@Nonnull String fingerprint) {
String fp = fingerprint.trim().toUpperCase();
if (!isValid(fp)) {
throw new IllegalArgumentException("Fingerprint " + fingerprint +
@ -51,26 +49,26 @@ public class OpenPgpV4Fingerprint implements CharSequence, Comparable<OpenPgpV4F
this.fingerprint = fp;
}
public OpenPgpV4Fingerprint(byte[] bytes) {
public OpenPgpV4Fingerprint(@Nonnull byte[] bytes) {
this(new String(bytes, Charset.forName("UTF-8")));
}
public OpenPgpV4Fingerprint(PGPPublicKey key) {
public OpenPgpV4Fingerprint(@Nonnull PGPPublicKey key) {
this(Hex.encode(key.getFingerprint()));
if (key.getVersion() != 4) {
throw new IllegalArgumentException("Key is not a v4 OpenPgp key.");
}
}
public OpenPgpV4Fingerprint(PGPSecretKey key) {
public OpenPgpV4Fingerprint(@Nonnull PGPSecretKey key) {
this(key.getPublicKey());
}
public OpenPgpV4Fingerprint(PGPPublicKeyRing ring) {
public OpenPgpV4Fingerprint(@Nonnull PGPPublicKeyRing ring) {
this(ring.getPublicKey());
}
public OpenPgpV4Fingerprint(PGPSecretKeyRing ring) {
public OpenPgpV4Fingerprint(@Nonnull PGPSecretKeyRing ring) {
this(ring.getPublicKey());
}
@ -79,7 +77,7 @@ public class OpenPgpV4Fingerprint implements CharSequence, Comparable<OpenPgpV4F
* @param fp fingerprint to check.
* @return true if fingerprint is valid.
*/
private boolean isValid(String fp) {
private static boolean isValid(@Nonnull String fp) {
return fp.matches("[0-9A-F]{40}");
}
@ -143,7 +141,7 @@ public class OpenPgpV4Fingerprint implements CharSequence, Comparable<OpenPgpV4F
}
@Override
public int compareTo(OpenPgpV4Fingerprint openPgpV4Fingerprint) {
public int compareTo(@Nonnull OpenPgpV4Fingerprint openPgpV4Fingerprint) {
return fingerprint.compareTo(openPgpV4Fingerprint.fingerprint);
}
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.collection;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@ -36,12 +37,17 @@ public class KeyRingCollection {
private PGPPublicKeyRingCollection publicKeys;
private PGPSecretKeyRingCollection secretKeys;
public KeyRingCollection(PGPPublicKeyRingCollection publicKeyRings, PGPSecretKeyRingCollection secretKeyRings) {
public KeyRingCollection(@Nonnull PGPPublicKeyRingCollection publicKeyRings, @Nonnull PGPSecretKeyRingCollection secretKeyRings) {
this.publicKeys = publicKeyRings;
this.secretKeys = secretKeyRings;
}
public KeyRingCollection(File pubRingFile, File secRingFile) throws IOException, PGPException {
if (pubRingFile == null && secRingFile == null) {
throw new NullPointerException("pubRingFile and secRingFile cannot BOTH be null.");
}
if (pubRingFile != null) {
InputStream pubRingIn = new FileInputStream(pubRingFile);
this.publicKeys = PGPainless.readKeyRing().publicKeyRingCollection(pubRingIn);
@ -55,15 +61,15 @@ public class KeyRingCollection {
}
}
public KeyRingCollection(PGPPublicKeyRingCollection publicKeyRings) {
this(publicKeyRings, null);
public KeyRingCollection(@Nonnull PGPPublicKeyRingCollection publicKeyRings) {
this.publicKeys = publicKeyRings;
}
public KeyRingCollection(PGPSecretKeyRingCollection secretKeyRings) {
this(null, secretKeyRings);
public KeyRingCollection(@Nonnull PGPSecretKeyRingCollection secretKeyRings) {
this.secretKeys = secretKeyRings;
}
public void importPublicKeys(PGPPublicKeyRingCollection publicKeyRings) {
public void importPublicKeys(@Nonnull PGPPublicKeyRingCollection publicKeyRings) {
if (this.publicKeys == null) {
this.publicKeys = publicKeyRings;
return;
@ -80,7 +86,7 @@ public class KeyRingCollection {
}
}
public void importSecretKeys(PGPSecretKeyRingCollection secretKeyRings) {
public void importSecretKeys(@Nonnull PGPSecretKeyRingCollection secretKeyRings) {
if (this.secretKeys == null) {
this.secretKeys = secretKeyRings;
return;

View File

@ -15,6 +15,9 @@
*/
package org.pgpainless.key.collection;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
@ -25,26 +28,29 @@ public class PGPKeyRing {
private PGPPublicKeyRing publicKeys;
private PGPSecretKeyRing secretKeys;
public PGPKeyRing(PGPPublicKeyRing publicKeys, PGPSecretKeyRing secretKeys) {
if (secretKeys == null && publicKeys == null) {
throw new IllegalArgumentException("publicKeys and secretKeys MUST NOT be both null.");
}
public PGPKeyRing(@Nonnull PGPPublicKeyRing publicKeys, @Nonnull PGPSecretKeyRing secretKeys) {
if (publicKeys != null && secretKeys != null) {
if (publicKeys.getPublicKey().getKeyID() != secretKeys.getPublicKey().getKeyID()) {
throw new IllegalArgumentException("publicKeys and secretKeys must have the same master key.");
}
if (publicKeys.getPublicKey().getKeyID() != secretKeys.getPublicKey().getKeyID()) {
throw new IllegalArgumentException("publicKeys and secretKeys must have the same master key.");
}
this.publicKeys = publicKeys;
this.secretKeys = secretKeys;
}
public PGPKeyRing(@Nonnull PGPPublicKeyRing publicKeys) {
this.publicKeys = publicKeys;
}
public PGPKeyRing(@Nonnull PGPSecretKeyRing secretKeys) {
this.secretKeys = secretKeys;
}
public long getKeyId() {
return getMasterKey().getKeyID();
}
public PGPPublicKey getMasterKey() {
public @Nonnull PGPPublicKey getMasterKey() {
PGPPublicKey publicKey = hasSecretKeys() ? secretKeys.getPublicKey() : publicKeys.getPublicKey();
if (!publicKey.isMasterKey()) {
throw new IllegalStateException("Expected master key is not a master key");
@ -52,7 +58,7 @@ public class PGPKeyRing {
return publicKey;
}
public OpenPgpV4Fingerprint getV4Fingerprint() {
public @Nonnull OpenPgpV4Fingerprint getV4Fingerprint() {
return new OpenPgpV4Fingerprint(getMasterKey());
}
@ -60,11 +66,11 @@ public class PGPKeyRing {
return secretKeys != null;
}
public PGPPublicKeyRing getPublicKeys() {
public @Nullable PGPPublicKeyRing getPublicKeys() {
return publicKeys;
}
public PGPSecretKeyRing getSecretKeys() {
public @Nullable PGPSecretKeyRing getSecretKeys() {
return secretKeys;
}
}

View File

@ -16,6 +16,7 @@
package org.pgpainless.key.generation;
import javax.annotation.Nonnull;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
@ -75,7 +76,7 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
* @throws NoSuchProviderException
* @throws InvalidAlgorithmParameterException
*/
public PGPKeyRing simpleRsaKeyRing(String userId, RsaLength length)
public PGPKeyRing simpleRsaKeyRing(@Nonnull String userId, @Nonnull RsaLength length)
throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
return withMasterKey(
KeySpec.getBuilder(RSA_GENERAL.withLength(length))
@ -98,7 +99,7 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
* @throws NoSuchProviderException
* @throws InvalidAlgorithmParameterException
*/
public PGPKeyRing simpleEcKeyRing(String userId)
public PGPKeyRing simpleEcKeyRing(@Nonnull String userId)
throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
return withSubKey(
KeySpec.getBuilder(ECDH.fromCurve(EllipticCurve._P256))
@ -114,13 +115,13 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
}
@Override
public KeyRingBuilderInterface withSubKey(KeySpec type) {
public KeyRingBuilderInterface withSubKey(@Nonnull KeySpec type) {
KeyRingBuilder.this.keySpecs.add(type);
return this;
}
@Override
public WithPrimaryUserId withMasterKey(KeySpec spec) {
public WithPrimaryUserId withMasterKey(@Nonnull KeySpec spec) {
if ((spec.getSubpackets().getKeyFlags() & KeyFlags.CERTIFY_OTHER) == 0) {
throw new IllegalArgumentException("Certification Key MUST have KeyFlag CERTIFY_OTHER");
}
@ -131,13 +132,13 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
class WithPrimaryUserIdImpl implements WithPrimaryUserId {
@Override
public WithPassphrase withPrimaryUserId(String userId) {
public WithPassphrase withPrimaryUserId(@Nonnull String userId) {
KeyRingBuilder.this.userId = userId;
return new WithPassphraseImpl();
}
@Override
public WithPassphrase withPrimaryUserId(byte[] userId) {
public WithPassphrase withPrimaryUserId(@Nonnull byte[] userId) {
return withPrimaryUserId(new String(userId, UTF8));
}
}
@ -145,7 +146,7 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
class WithPassphraseImpl implements WithPassphrase {
@Override
public Build withPassphrase(Passphrase passphrase) {
public Build withPassphrase(@Nonnull Passphrase passphrase) {
KeyRingBuilder.this.passphrase = passphrase;
return new BuildImpl();
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.generation;
import javax.annotation.Nonnull;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
@ -25,21 +26,21 @@ import org.pgpainless.util.Passphrase;
public interface KeyRingBuilderInterface {
KeyRingBuilderInterface withSubKey(KeySpec keySpec);
KeyRingBuilderInterface withSubKey(@Nonnull KeySpec keySpec);
WithPrimaryUserId withMasterKey(KeySpec keySpec);
WithPrimaryUserId withMasterKey(@Nonnull KeySpec keySpec);
interface WithPrimaryUserId {
WithPassphrase withPrimaryUserId(String userId);
WithPassphrase withPrimaryUserId(@Nonnull String userId);
WithPassphrase withPrimaryUserId(byte[] userId);
WithPassphrase withPrimaryUserId(@Nonnull byte[] userId);
}
interface WithPassphrase {
Build withPassphrase(Passphrase passphrase);
Build withPassphrase(@Nonnull Passphrase passphrase);
Build withoutPassphrase();
}

View File

@ -15,6 +15,9 @@
*/
package org.pgpainless.key.generation;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
import org.pgpainless.key.generation.type.KeyType;
@ -25,20 +28,22 @@ public class KeySpec {
private final PGPSignatureSubpacketGenerator subpacketGenerator;
private final boolean inheritedSubPackets;
KeySpec(KeyType type,
PGPSignatureSubpacketGenerator subpacketGenerator,
KeySpec(@Nonnull KeyType type,
@Nullable PGPSignatureSubpacketGenerator subpacketGenerator,
boolean inheritedSubPackets) {
this.keyType = type;
this.subpacketGenerator = subpacketGenerator;
this.inheritedSubPackets = inheritedSubPackets;
}
@Nonnull
KeyType getKeyType() {
return keyType;
}
@Nullable
PGPSignatureSubpacketVector getSubpackets() {
return subpacketGenerator.generate();
return subpacketGenerator != null ? subpacketGenerator.generate() : null;
}
boolean isInheritedSubPackets() {

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.generation;
import javax.annotation.Nonnull;
import org.bouncycastle.bcpg.sig.Features;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.pgpainless.algorithm.AlgorithmSuite;
@ -30,12 +32,12 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
private KeyType type;
private PGPSignatureSubpacketGenerator hashedSubPackets = new PGPSignatureSubpacketGenerator();
KeySpecBuilder(KeyType type) {
KeySpecBuilder(@Nonnull KeyType type) {
this.type = type;
}
@Override
public WithDetailedConfiguration withKeyFlags(KeyFlag... flags) {
public WithDetailedConfiguration withKeyFlags(@Nonnull KeyFlag... flags) {
int val = 0;
for (KeyFlag f : flags) {
val |= f.getFlag();
@ -74,6 +76,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
hashedSubPackets.setPreferredSymmetricAlgorithms(false, defaultSuite.getSymmetricKeyAlgorithmIds());
hashedSubPackets.setPreferredHashAlgorithms(false, defaultSuite.getHashAlgorithmIds());
hashedSubPackets.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION);
return new KeySpec(
KeySpecBuilder.this.type,
KeySpecBuilder.this.hashedSubPackets,
@ -84,7 +87,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
class WithPreferredSymmetricAlgorithmsImpl implements WithPreferredSymmetricAlgorithms {
@Override
public WithPreferredHashAlgorithms withPreferredSymmetricAlgorithms(SymmetricKeyAlgorithm... algorithms) {
public WithPreferredHashAlgorithms withPreferredSymmetricAlgorithms(@Nonnull SymmetricKeyAlgorithm... algorithms) {
int[] ids = new int[algorithms.length];
for (int i = 0; i < ids.length; i++) {
ids[i] = algorithms[i].getAlgorithmId();
@ -115,7 +118,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
class WithPreferredHashAlgorithmsImpl implements WithPreferredHashAlgorithms {
@Override
public WithPreferredCompressionAlgorithms withPreferredHashAlgorithms(HashAlgorithm... algorithms) {
public WithPreferredCompressionAlgorithms withPreferredHashAlgorithms(@Nonnull HashAlgorithm... algorithms) {
int[] ids = new int[algorithms.length];
for (int i = 0; i < ids.length; i++) {
ids[i] = algorithms[i].getAlgorithmId();
@ -135,7 +138,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
class WithPreferredCompressionAlgorithmsImpl implements WithPreferredCompressionAlgorithms {
@Override
public WithFeatures withPreferredCompressionAlgorithms(CompressionAlgorithm... algorithms) {
public WithFeatures withPreferredCompressionAlgorithms(@Nonnull CompressionAlgorithm... algorithms) {
int[] ids = new int[algorithms.length];
for (int i = 0; i < ids.length; i++) {
ids[i] = algorithms[i].getAlgorithmId();
@ -155,7 +158,7 @@ public class KeySpecBuilder implements KeySpecBuilderInterface {
class WithFeaturesImpl implements WithFeatures {
@Override
public WithFeatures withFeature(Feature feature) {
public WithFeatures withFeature(@Nonnull Feature feature) {
KeySpecBuilder.this.hashedSubPackets.setFeature(false, feature.getFeatureId());
return this;
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.generation;
import javax.annotation.Nonnull;
import org.pgpainless.algorithm.CompressionAlgorithm;
import org.pgpainless.algorithm.Feature;
import org.pgpainless.algorithm.HashAlgorithm;
@ -23,7 +25,7 @@ import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
public interface KeySpecBuilderInterface {
WithDetailedConfiguration withKeyFlags(KeyFlag... flags);
WithDetailedConfiguration withKeyFlags(@Nonnull KeyFlag... flags);
WithDetailedConfiguration withDefaultKeyFlags();
@ -38,7 +40,7 @@ public interface KeySpecBuilderInterface {
interface WithPreferredSymmetricAlgorithms {
WithPreferredHashAlgorithms withPreferredSymmetricAlgorithms(SymmetricKeyAlgorithm... algorithms);
WithPreferredHashAlgorithms withPreferredSymmetricAlgorithms(@Nonnull SymmetricKeyAlgorithm... algorithms);
WithPreferredHashAlgorithms withDefaultSymmetricAlgorithms();
@ -48,7 +50,7 @@ public interface KeySpecBuilderInterface {
interface WithPreferredHashAlgorithms {
WithPreferredCompressionAlgorithms withPreferredHashAlgorithms(HashAlgorithm... algorithms);
WithPreferredCompressionAlgorithms withPreferredHashAlgorithms(@Nonnull HashAlgorithm... algorithms);
WithPreferredCompressionAlgorithms withDefaultHashAlgorithms();
@ -56,7 +58,7 @@ public interface KeySpecBuilderInterface {
interface WithPreferredCompressionAlgorithms {
WithFeatures withPreferredCompressionAlgorithms(CompressionAlgorithm... algorithms);
WithFeatures withPreferredCompressionAlgorithms(@Nonnull CompressionAlgorithm... algorithms);
WithFeatures withDefaultCompressionAlgorithms();
@ -64,7 +66,7 @@ public interface KeySpecBuilderInterface {
interface WithFeatures {
WithFeatures withFeature(Feature feature);
WithFeatures withFeature(@Nonnull Feature feature);
KeySpec done();
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.generation.type;
import javax.annotation.Nonnull;
import java.security.spec.AlgorithmParameterSpec;
import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
@ -29,7 +30,7 @@ public class ECDH implements KeyType {
this.curve = curve;
}
public static ECDH fromCurve(EllipticCurve curve) {
public static ECDH fromCurve(@Nonnull EllipticCurve curve) {
return new ECDH(curve);
}

View File

@ -16,16 +16,18 @@
package org.pgpainless.key.generation.type;
import javax.annotation.Nonnull;
import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.key.generation.type.curve.EllipticCurve;
public class ECDSA extends ECDH {
ECDSA(EllipticCurve curve) {
ECDSA(@Nonnull EllipticCurve curve) {
super(curve);
}
public static ECDSA fromCurve(EllipticCurve curve) {
public static ECDSA fromCurve(@Nonnull EllipticCurve curve) {
return new ECDSA(curve);
}

View File

@ -15,12 +15,14 @@
*/
package org.pgpainless.key.generation.type;
import javax.annotation.Nonnull;
import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.key.generation.type.length.ElGamalLength;
public class ElGamal_ENCRYPT extends ElGamal_GENERAL {
ElGamal_ENCRYPT(ElGamalLength length) {
ElGamal_ENCRYPT(@Nonnull ElGamalLength length) {
super(length);
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.generation.type;
import javax.annotation.Nonnull;
import java.security.spec.AlgorithmParameterSpec;
import org.bouncycastle.jce.spec.ElGamalParameterSpec;
@ -25,11 +26,11 @@ public class ElGamal_GENERAL implements KeyType {
private final ElGamalLength length;
ElGamal_GENERAL(ElGamalLength length) {
ElGamal_GENERAL(@Nonnull ElGamalLength length) {
this.length = length;
}
public static ElGamal_GENERAL withLength(ElGamalLength length) {
public static ElGamal_GENERAL withLength(@Nonnull ElGamalLength length) {
return new ElGamal_GENERAL(length);
}

View File

@ -15,12 +15,14 @@
*/
package org.pgpainless.key.generation.type;
import javax.annotation.Nonnull;
import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.key.generation.type.length.RsaLength;
public class RSA_ENCRYPT extends RSA_GENERAL {
RSA_ENCRYPT(RsaLength length) {
RSA_ENCRYPT(@Nonnull RsaLength length) {
super(length);
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.generation.type;
import javax.annotation.Nonnull;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
@ -25,11 +26,11 @@ public class RSA_GENERAL implements KeyType {
private final RsaLength length;
RSA_GENERAL(RsaLength length) {
RSA_GENERAL(@Nonnull RsaLength length) {
this.length = length;
}
public static RSA_GENERAL withLength(RsaLength length) {
public static RSA_GENERAL withLength(@Nonnull RsaLength length) {
return new RSA_GENERAL(length);
}

View File

@ -15,12 +15,14 @@
*/
package org.pgpainless.key.generation.type;
import javax.annotation.Nonnull;
import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.key.generation.type.length.RsaLength;
public class RSA_SIGN extends RSA_GENERAL {
RSA_SIGN(RsaLength length) {
RSA_SIGN(@Nonnull RsaLength length) {
super(length);
}

View File

@ -15,13 +15,15 @@
*/
package org.pgpainless.key.generation.type.curve;
import javax.annotation.Nonnull;
public enum EllipticCurve {
_P256("P-256"),
;
private final String name;
EllipticCurve(String name) {
EllipticCurve(@Nonnull String name) {
this.name = name;
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.parsing;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@ -33,68 +35,68 @@ public class KeyRingReader {
public static final Charset UTF8 = Charset.forName("UTF-8");
public PGPPublicKeyRing publicKeyRing(InputStream inputStream) throws IOException {
public @Nonnull PGPPublicKeyRing publicKeyRing(@Nonnull InputStream inputStream) throws IOException {
return readPublicKeyRing(inputStream);
}
public PGPPublicKeyRing publicKeyRing(byte[] bytes) throws IOException {
public PGPPublicKeyRing publicKeyRing(@Nonnull byte[] bytes) throws IOException {
return publicKeyRing(new ByteArrayInputStream(bytes));
}
public PGPPublicKeyRing publicKeyRing(String asciiArmored) throws IOException {
public PGPPublicKeyRing publicKeyRing(@Nonnull String asciiArmored) throws IOException {
return publicKeyRing(asciiArmored.getBytes(UTF8));
}
public PGPPublicKeyRingCollection publicKeyRingCollection(InputStream inputStream)
public PGPPublicKeyRingCollection publicKeyRingCollection(@Nonnull InputStream inputStream)
throws IOException, PGPException {
return readPublicKeyRingCollection(inputStream);
}
public PGPPublicKeyRingCollection publicKeyRingCollection(byte[] bytes) throws IOException, PGPException {
public PGPPublicKeyRingCollection publicKeyRingCollection(@Nonnull byte[] bytes) throws IOException, PGPException {
return publicKeyRingCollection(new ByteArrayInputStream(bytes));
}
public PGPPublicKeyRingCollection publicKeyRingCollection(String asciiArmored) throws IOException, PGPException {
public PGPPublicKeyRingCollection publicKeyRingCollection(@Nonnull String asciiArmored) throws IOException, PGPException {
return publicKeyRingCollection(asciiArmored.getBytes(UTF8));
}
public PGPSecretKeyRing secretKeyRing(InputStream inputStream) throws IOException, PGPException {
public PGPSecretKeyRing secretKeyRing(@Nonnull InputStream inputStream) throws IOException, PGPException {
return readSecretKeyRing(inputStream);
}
public PGPSecretKeyRing secretKeyRing(byte[] bytes) throws IOException, PGPException {
public PGPSecretKeyRing secretKeyRing(@Nonnull byte[] bytes) throws IOException, PGPException {
return secretKeyRing(new ByteArrayInputStream(bytes));
}
public PGPSecretKeyRing secretKeyRing(String asciiArmored) throws IOException, PGPException {
public PGPSecretKeyRing secretKeyRing(@Nonnull String asciiArmored) throws IOException, PGPException {
return secretKeyRing(asciiArmored.getBytes(UTF8));
}
public PGPSecretKeyRingCollection secretKeyRingCollection(InputStream inputStream)
public PGPSecretKeyRingCollection secretKeyRingCollection(@Nonnull InputStream inputStream)
throws IOException, PGPException {
return readSecretKeyRingCollection(inputStream);
}
public PGPSecretKeyRingCollection secretKeyRingCollection(byte[] bytes) throws IOException, PGPException {
public PGPSecretKeyRingCollection secretKeyRingCollection(@Nonnull byte[] bytes) throws IOException, PGPException {
return secretKeyRingCollection(new ByteArrayInputStream(bytes));
}
public PGPSecretKeyRingCollection secretKeyRingCollection(String asciiArmored) throws IOException, PGPException {
public PGPSecretKeyRingCollection secretKeyRingCollection(@Nonnull String asciiArmored) throws IOException, PGPException {
return secretKeyRingCollection(asciiArmored.getBytes(UTF8));
}
public PGPKeyRing keyRing(InputStream publicIn, InputStream secretIn) throws IOException, PGPException {
public PGPKeyRing keyRing(@Nullable InputStream publicIn, @Nullable InputStream secretIn) throws IOException, PGPException {
return readKeyRing(publicIn, secretIn);
}
public PGPKeyRing keyRing(byte[] publicBytes, byte[] secretBytes) throws IOException, PGPException {
public PGPKeyRing keyRing(@Nullable byte[] publicBytes, @Nullable byte[] secretBytes) throws IOException, PGPException {
return keyRing(
publicBytes != null ? new ByteArrayInputStream(publicBytes) : null,
secretBytes != null ? new ByteArrayInputStream(secretBytes) : null
);
}
public PGPKeyRing keyRing(String asciiPublic, String asciiSecret) throws IOException, PGPException {
public PGPKeyRing keyRing(@Nullable String asciiPublic, @Nullable String asciiSecret) throws IOException, PGPException {
return keyRing(
asciiPublic != null ? asciiPublic.getBytes(UTF8) : null,
asciiSecret != null ? asciiSecret.getBytes(UTF8) : null
@ -105,33 +107,38 @@ public class KeyRingReader {
STATIC METHODS
*/
public static PGPPublicKeyRing readPublicKeyRing(InputStream inputStream) throws IOException {
public static PGPPublicKeyRing readPublicKeyRing(@Nonnull InputStream inputStream) throws IOException {
return new PGPPublicKeyRing(
PGPUtil.getDecoderStream(inputStream),
new BcKeyFingerprintCalculator());
}
public static PGPPublicKeyRingCollection readPublicKeyRingCollection(InputStream inputStream)
public static PGPPublicKeyRingCollection readPublicKeyRingCollection(@Nonnull InputStream inputStream)
throws IOException, PGPException {
return new PGPPublicKeyRingCollection(
PGPUtil.getDecoderStream(inputStream),
new BcKeyFingerprintCalculator());
}
public static PGPSecretKeyRing readSecretKeyRing(InputStream inputStream) throws IOException, PGPException {
public static PGPSecretKeyRing readSecretKeyRing(@Nonnull InputStream inputStream) throws IOException, PGPException {
return new PGPSecretKeyRing(
PGPUtil.getDecoderStream(inputStream),
new BcKeyFingerprintCalculator());
}
public static PGPSecretKeyRingCollection readSecretKeyRingCollection(InputStream inputStream)
public static PGPSecretKeyRingCollection readSecretKeyRingCollection(@Nonnull InputStream inputStream)
throws IOException, PGPException {
return new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(inputStream),
new BcKeyFingerprintCalculator());
}
public static PGPKeyRing readKeyRing(InputStream publicIn, InputStream secretIn) throws IOException, PGPException {
public static PGPKeyRing readKeyRing(@Nullable InputStream publicIn, @Nullable InputStream secretIn) throws IOException, PGPException {
if (publicIn == null && secretIn == null) {
throw new NullPointerException("publicIn and secretIn cannot be BOTH null.");
}
PGPPublicKeyRing publicKeys = null;
if (publicIn != null) {
publicKeys = readPublicKeyRing(publicIn);
@ -140,6 +147,15 @@ public class KeyRingReader {
if (secretIn != null) {
secretKeys = readSecretKeyRing(secretIn);
}
if (secretKeys == null) {
return new PGPKeyRing(publicKeys);
}
if (publicKeys == null) {
return new PGPKeyRing(secretKeys);
}
return new PGPKeyRing(publicKeys, secretKeys);
}
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.protection;
import javax.annotation.Nonnull;
import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
@ -24,17 +26,20 @@ public class KeyRingProtectionSettings {
private final HashAlgorithm hashAlgorithm;
private final int s2kCount;
public KeyRingProtectionSettings(SymmetricKeyAlgorithm encryptionAlgorithm, HashAlgorithm hashAlgorithm, int s2kCount) {
public KeyRingProtectionSettings(@Nonnull SymmetricKeyAlgorithm encryptionAlgorithm, @Nonnull HashAlgorithm hashAlgorithm, int s2kCount) {
this.encryptionAlgorithm = encryptionAlgorithm;
this.hashAlgorithm = hashAlgorithm;
if (s2kCount > 1) {
throw new IllegalArgumentException("s2kCount cannot be less than 1.");
}
this.s2kCount = s2kCount;
}
public SymmetricKeyAlgorithm getEncryptionAlgorithm() {
public @Nonnull SymmetricKeyAlgorithm getEncryptionAlgorithm() {
return encryptionAlgorithm;
}
public HashAlgorithm getHashAlgorithm() {
public @Nonnull HashAlgorithm getHashAlgorithm() {
return hashAlgorithm;
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.protection;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
@ -34,9 +36,9 @@ public class PassphraseMapKeyRingProtector implements SecretKeyRingProtector, Se
private final SecretKeyRingProtector protector;
private final SecretKeyPassphraseProvider provider;
public PassphraseMapKeyRingProtector(Map<Long, Passphrase> passphrases,
KeyRingProtectionSettings protectionSettings,
SecretKeyPassphraseProvider missingPassphraseCallback) {
public PassphraseMapKeyRingProtector(@Nonnull Map<Long, Passphrase> passphrases,
@Nonnull KeyRingProtectionSettings protectionSettings,
@Nullable SecretKeyPassphraseProvider missingPassphraseCallback) {
this.cache.putAll(passphrases);
this.protector = new PasswordBasedSecretKeyRingProtector(protectionSettings, this);
this.provider = missingPassphraseCallback;
@ -48,7 +50,7 @@ public class PassphraseMapKeyRingProtector implements SecretKeyRingProtector, Se
* @param keyId id of the key
* @param passphrase passphrase
*/
public void addPassphrase(Long keyId, Passphrase passphrase) {
public void addPassphrase(@Nonnull Long keyId, @Nullable Passphrase passphrase) {
this.cache.put(keyId, passphrase);
}
@ -58,14 +60,15 @@ public class PassphraseMapKeyRingProtector implements SecretKeyRingProtector, Se
*
* @param keyId id of the key
*/
public void forgetPassphrase(Long keyId) {
public void forgetPassphrase(@Nonnull Long keyId) {
Passphrase passphrase = cache.get(keyId);
passphrase.clear();
cache.remove(keyId);
}
@Override
public Passphrase getPassphraseFor(Long keyId) {
@Nullable
public Passphrase getPassphraseFor(@Nonnull Long keyId) {
Passphrase passphrase = cache.get(keyId);
if (passphrase == null || !passphrase.isValid()) {
passphrase = provider.getPassphraseFor(keyId);
@ -77,12 +80,14 @@ public class PassphraseMapKeyRingProtector implements SecretKeyRingProtector, Se
}
@Override
public PBESecretKeyDecryptor getDecryptor(Long keyId) {
@Nullable
public PBESecretKeyDecryptor getDecryptor(@Nonnull Long keyId) {
return protector.getDecryptor(keyId);
}
@Override
public PBESecretKeyEncryptor getEncryptor(Long keyId) throws PGPException {
@Nullable
public PBESecretKeyEncryptor getEncryptor(@Nonnull Long keyId) throws PGPException {
return protector.getEncryptor(keyId);
}
}

View File

@ -15,6 +15,9 @@
*/
package org.pgpainless.key.protection;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
@ -43,12 +46,13 @@ public class PasswordBasedSecretKeyRingProtector implements SecretKeyRingProtect
* @param settings S2K settings etc.
* @param passphraseProvider provider which provides passphrases.
*/
public PasswordBasedSecretKeyRingProtector(KeyRingProtectionSettings settings, SecretKeyPassphraseProvider passphraseProvider) {
public PasswordBasedSecretKeyRingProtector(@Nonnull KeyRingProtectionSettings settings, @Nonnull SecretKeyPassphraseProvider passphraseProvider) {
this.protectionSettings = settings;
this.passphraseProvider = passphraseProvider;
}
@Override
@Nullable
public PBESecretKeyDecryptor getDecryptor(Long keyId) {
Passphrase passphrase = passphraseProvider.getPassphraseFor(keyId);
return new BcPBESecretKeyDecryptorBuilder(calculatorProvider)
@ -56,6 +60,7 @@ public class PasswordBasedSecretKeyRingProtector implements SecretKeyRingProtect
}
@Override
@Nullable
public PBESecretKeyEncryptor getEncryptor(Long keyId) throws PGPException {
Passphrase passphrase = passphraseProvider.getPassphraseFor(keyId);
return new BcPBESecretKeyEncryptorBuilder(

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.protection;
import javax.annotation.Nullable;
import org.pgpainless.util.Passphrase;
/**
@ -23,10 +25,12 @@ import org.pgpainless.util.Passphrase;
public interface SecretKeyPassphraseProvider {
/**
* Return a passphrase for the given key.
* Return a passphrase for the given key. If no record has been found, return null.
* Note: In case of an unprotected secret key, this method must may not return null, but a {@link Passphrase} with
* a content of null.
*
* @param keyId id of the key
* @return passphrase
* @return passphrase or null, if no passphrase record has been found.
*/
Passphrase getPassphraseFor(Long keyId);
@Nullable Passphrase getPassphraseFor(Long keyId);
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.protection;
import javax.annotation.Nullable;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
@ -23,19 +25,21 @@ public interface SecretKeyRingProtector {
/**
* Return a decryptor for the key of id {@code keyId}.
* This method returns null if the key is unprotected.
*
* @param keyId id of the key
* @return decryptor for the key
*/
PBESecretKeyDecryptor getDecryptor(Long keyId);
@Nullable PBESecretKeyDecryptor getDecryptor(Long keyId);
/**
* Return an encryptor for the key of id {@code keyId}.
* This method returns null if the key is unprotected.
*
* @param keyId id of the key
* @return encryptor for the key
* @throws PGPException if the encryptor cannot be created for some reason
*/
PBESecretKeyEncryptor getEncryptor(Long keyId) throws PGPException;
@Nullable PBESecretKeyEncryptor getEncryptor(Long keyId) throws PGPException;
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.protection;
import javax.annotation.Nullable;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
@ -22,12 +24,15 @@ import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
* Implementation of the {@link SecretKeyRingProtector} which assumes that all handled keys are not password protected.
*/
public class UnprotectedKeysProtector implements SecretKeyRingProtector {
@Override
@Nullable
public PBESecretKeyDecryptor getDecryptor(Long keyId) {
return null;
}
@Override
@Nullable
public PBESecretKeyEncryptor getEncryptor(Long keyId) {
return null;
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.selection.key;
import javax.annotation.Nonnull;
import java.util.Set;
import org.pgpainless.util.MultiMap;
@ -30,7 +31,7 @@ public interface KeySelectionStrategy<K, R, O> {
boolean accept(O identifier, K key);
Set<K> selectKeysFromKeyRing(O identifier, R ring);
Set<K> selectKeysFromKeyRing(O identifier, @Nonnull R ring);
MultiMap<O, K> selectKeysFromKeyRings(MultiMap<O, R> rings);

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.selection.key;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
@ -32,7 +33,7 @@ import org.pgpainless.util.MultiMap;
public abstract class PublicKeySelectionStrategy<O> implements KeySelectionStrategy<PGPPublicKey, PGPPublicKeyRing, O> {
@Override
public Set<PGPPublicKey> selectKeysFromKeyRing(O identifier, PGPPublicKeyRing ring) {
public Set<PGPPublicKey> selectKeysFromKeyRing(O identifier, @Nonnull PGPPublicKeyRing ring) {
Set<PGPPublicKey> keys = new HashSet<>();
for (Iterator<PGPPublicKey> i = ring.getPublicKeys(); i.hasNext(); ) {
PGPPublicKey key = i.next();
@ -42,7 +43,7 @@ public abstract class PublicKeySelectionStrategy<O> implements KeySelectionStrat
}
@Override
public MultiMap<O, PGPPublicKey> selectKeysFromKeyRings(MultiMap<O, PGPPublicKeyRing> keyRings) {
public MultiMap<O, PGPPublicKey> selectKeysFromKeyRings(@Nonnull MultiMap<O, PGPPublicKeyRing> keyRings) {
MultiMap<O, PGPPublicKey> keys = new MultiMap<>();
for (O identifier : keyRings.keySet()) {
for (PGPPublicKeyRing ring : keyRings.get(identifier)) {

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.selection.key;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
@ -32,7 +33,7 @@ import org.pgpainless.util.MultiMap;
public abstract class SecretKeySelectionStrategy<O> implements KeySelectionStrategy<PGPSecretKey, PGPSecretKeyRing, O> {
@Override
public Set<PGPSecretKey> selectKeysFromKeyRing(O identifier, PGPSecretKeyRing ring) {
public Set<PGPSecretKey> selectKeysFromKeyRing(O identifier, @Nonnull PGPSecretKeyRing ring) {
Set<PGPSecretKey> keys = new HashSet<>();
for (Iterator<PGPSecretKey> i = ring.getSecretKeys(); i.hasNext(); ) {
PGPSecretKey key = i.next();
@ -42,7 +43,7 @@ public abstract class SecretKeySelectionStrategy<O> implements KeySelectionStrat
}
@Override
public MultiMap<O, PGPSecretKey> selectKeysFromKeyRings(MultiMap<O, PGPSecretKeyRing> keyRings) {
public MultiMap<O, PGPSecretKey> selectKeysFromKeyRings(@Nonnull MultiMap<O, PGPSecretKeyRing> keyRings) {
MultiMap<O, PGPSecretKey> keys = new MultiMap<>();
for (O identifier : keyRings.keySet()) {
for (PGPSecretKeyRing ring : keyRings.get(identifier)) {

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.selection.key.impl;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.pgpainless.key.selection.key.PublicKeySelectionStrategy;
@ -27,8 +29,8 @@ public class And {
private final PublicKeySelectionStrategy<O> left;
private final PublicKeySelectionStrategy<O> right;
public PubKeySelectionStrategy(PublicKeySelectionStrategy<O> left,
PublicKeySelectionStrategy<O> right) {
public PubKeySelectionStrategy(@Nonnull PublicKeySelectionStrategy<O> left,
@Nonnull PublicKeySelectionStrategy<O> right) {
this.left = left;
this.right = right;
}
@ -44,8 +46,8 @@ public class And {
private final SecretKeySelectionStrategy<O> left;
private final SecretKeySelectionStrategy<O> right;
public SecKeySelectionStrategy(SecretKeySelectionStrategy<O> left,
SecretKeySelectionStrategy<O> right) {
public SecKeySelectionStrategy(@Nonnull SecretKeySelectionStrategy<O> left,
@Nonnull SecretKeySelectionStrategy<O> right) {
this.left = left;
this.right = right;
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.selection.key.impl;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.pgpainless.key.selection.key.PublicKeySelectionStrategy;
@ -26,7 +28,7 @@ import org.pgpainless.key.selection.key.PublicKeySelectionStrategy;
public class EncryptionKeySelectionStrategy<O> extends PublicKeySelectionStrategy<O> {
@Override
public boolean accept(O identifier, PGPPublicKey key) {
public boolean accept(O identifier, @Nonnull PGPPublicKey key) {
return key.isEncryptionKey();
}
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.selection.key.impl;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.pgpainless.key.selection.key.PublicKeySelectionStrategy;
@ -33,7 +35,7 @@ public class NoRevocation {
public static class PubKeySelectionStrategy<O> extends PublicKeySelectionStrategy<O> {
@Override
public boolean accept(O identifier, PGPPublicKey key) {
public boolean accept(O identifier, @Nonnull PGPPublicKey key) {
return !key.hasRevocation();
}
}
@ -46,7 +48,7 @@ public class NoRevocation {
public static class SecKeySelectionStrategy<O> extends SecretKeySelectionStrategy<O> {
@Override
public boolean accept(O identifier, PGPSecretKey key) {
public boolean accept(O identifier, @Nonnull PGPSecretKey key) {
return !key.getPublicKey().hasRevocation();
}
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.selection.key.impl;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.pgpainless.key.selection.key.PublicKeySelectionStrategy;
@ -27,8 +29,8 @@ public class Or {
private final PublicKeySelectionStrategy<O> left;
private final PublicKeySelectionStrategy<O> right;
public PubKeySelectionStrategy(PublicKeySelectionStrategy<O> left,
PublicKeySelectionStrategy<O> right) {
public PubKeySelectionStrategy(@Nonnull PublicKeySelectionStrategy<O> left,
@Nonnull PublicKeySelectionStrategy<O> right) {
this.left = left;
this.right = right;
}
@ -44,8 +46,8 @@ public class Or {
private final SecretKeySelectionStrategy<O> left;
private final SecretKeySelectionStrategy<O> right;
public SecKeySelectionStrategy(SecretKeySelectionStrategy<O> left,
SecretKeySelectionStrategy<O> right) {
public SecKeySelectionStrategy(@Nonnull SecretKeySelectionStrategy<O> left,
@Nonnull SecretKeySelectionStrategy<O> right) {
this.left = left;
this.right = right;
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.selection.key.impl;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.pgpainless.key.selection.key.SecretKeySelectionStrategy;
@ -26,7 +28,7 @@ import org.pgpainless.key.selection.key.SecretKeySelectionStrategy;
public class SignatureKeySelectionStrategy<O> extends SecretKeySelectionStrategy<O> {
@Override
public boolean accept(O identifier, PGPSecretKey key) {
public boolean accept(O identifier, @Nonnull PGPSecretKey key) {
return key.isSigningKey();
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.selection.key.impl;
import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.Iterator;
import java.util.logging.Level;
@ -33,7 +34,7 @@ public class SignedByMasterKey {
public static class PubkeySelectionStrategy extends PublicKeySelectionStrategy<PGPPublicKey> {
@Override
public boolean accept(PGPPublicKey masterKey, PGPPublicKey key) {
public boolean accept(PGPPublicKey masterKey, @Nonnull PGPPublicKey key) {
// Same key -> accept
if (Arrays.equals(masterKey.getFingerprint(), key.getFingerprint())) {
return true;

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.selection.keyring;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
@ -26,7 +27,7 @@ import org.pgpainless.util.MultiMap;
public abstract class PublicKeyRingSelectionStrategy<O> implements KeyRingSelectionStrategy<PGPPublicKeyRing, PGPPublicKeyRingCollection, O> {
@Override
public Set<PGPPublicKeyRing> selectKeyRingsFromCollection(O identifier, PGPPublicKeyRingCollection keyRingCollection) {
public Set<PGPPublicKeyRing> selectKeyRingsFromCollection(@Nonnull O identifier, @Nonnull PGPPublicKeyRingCollection keyRingCollection) {
Set<PGPPublicKeyRing> accepted = new HashSet<>();
for (Iterator<PGPPublicKeyRing> i = keyRingCollection.getKeyRings(); i.hasNext(); ) {
PGPPublicKeyRing ring = i.next();
@ -36,7 +37,7 @@ public abstract class PublicKeyRingSelectionStrategy<O> implements KeyRingSelect
}
@Override
public MultiMap<O, PGPPublicKeyRing> selectKeyRingsFromCollections(MultiMap<O, PGPPublicKeyRingCollection> keyRingCollections) {
public MultiMap<O, PGPPublicKeyRing> selectKeyRingsFromCollections(@Nonnull MultiMap<O, PGPPublicKeyRingCollection> keyRingCollections) {
MultiMap<O, PGPPublicKeyRing> keyRings = new MultiMap<>();
for (O identifier : keyRingCollections.keySet()) {
for (PGPPublicKeyRingCollection collection : keyRingCollections.get(identifier)) {

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.selection.keyring;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
@ -25,7 +26,7 @@ import org.pgpainless.util.MultiMap;
public abstract class SecretKeyRingSelectionStrategy<O> implements KeyRingSelectionStrategy<PGPSecretKeyRing, PGPSecretKeyRingCollection, O> {
@Override
public Set<PGPSecretKeyRing> selectKeyRingsFromCollection(O identifier, PGPSecretKeyRingCollection keyRingCollection) {
public Set<PGPSecretKeyRing> selectKeyRingsFromCollection(O identifier, @Nonnull PGPSecretKeyRingCollection keyRingCollection) {
Set<PGPSecretKeyRing> accepted = new HashSet<>();
for (Iterator<PGPSecretKeyRing> i = keyRingCollection.getKeyRings(); i.hasNext(); ) {
PGPSecretKeyRing ring = i.next();
@ -35,7 +36,7 @@ public abstract class SecretKeyRingSelectionStrategy<O> implements KeyRingSelect
}
@Override
public MultiMap<O, PGPSecretKeyRing> selectKeyRingsFromCollections(MultiMap<O, PGPSecretKeyRingCollection> keyRingCollections) {
public MultiMap<O, PGPSecretKeyRing> selectKeyRingsFromCollections(@Nonnull MultiMap<O, PGPSecretKeyRingCollection> keyRingCollections) {
MultiMap<O, PGPSecretKeyRing> keyRings = new MultiMap<>();
for (O identifier : keyRingCollections.keySet()) {
for (PGPSecretKeyRingCollection collection : keyRingCollections.get(identifier)) {

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.key.selection.keyring.impl;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
@ -23,7 +25,7 @@ public class Email {
public static class PubRingSelectionStrategy extends PartialUserId.PubRingSelectionStrategy {
@Override
public boolean accept(String email, PGPPublicKey key) {
public boolean accept(@Nonnull String email, @Nonnull PGPPublicKey key) {
// Ensure, that email address is encapsulated in "<",">"
if (!email.matches("^<.+>$")) {
email = "<" + email + ">";

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.key.selection.keyring.impl;
import javax.annotation.Nonnull;
import java.util.Iterator;
import org.bouncycastle.openpgp.PGPPublicKey;
@ -27,7 +28,7 @@ public class PartialUserId {
public static class PubRingSelectionStrategy extends PublicKeySelectionStrategy<String> {
@Override
public boolean accept(String identifier, PGPPublicKey key) {
public boolean accept(String identifier, @Nonnull PGPPublicKey key) {
for (Iterator<String> userIds = key.getUserIDs(); userIds.hasNext(); ) {
String userId = userIds.next();
if (userId.contains(identifier)) {
@ -41,7 +42,7 @@ public class PartialUserId {
public static class SecRingSelectionStrategy extends SecretKeySelectionStrategy<String> {
@Override
public boolean accept(String identifier, PGPSecretKey key) {
public boolean accept(String identifier, @Nonnull PGPSecretKey key) {
for (Iterator userIds = key.getUserIDs(); userIds.hasNext(); ) {
String userId = (String) userIds.next();
if (userId.contains(identifier)) {

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.symmetric_encryption;
import javax.annotation.Nonnull;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -62,10 +63,10 @@ public class SymmetricEncryptorDecryptor {
* @throws IOException IO is dangerous
* @throws PGPException OpenPGP is brittle
*/
public static byte[] symmetricallyEncrypt(byte[] data,
Passphrase password,
SymmetricKeyAlgorithm encryptionAlgorithm,
CompressionAlgorithm compressionAlgorithm)
public static byte[] symmetricallyEncrypt(@Nonnull byte[] data,
@Nonnull Passphrase password,
@Nonnull SymmetricKeyAlgorithm encryptionAlgorithm,
@Nonnull CompressionAlgorithm compressionAlgorithm)
throws IOException, PGPException {
byte[] compressedData = compress(data, compressionAlgorithm.getAlgorithmId());
@ -99,7 +100,8 @@ public class SymmetricEncryptorDecryptor {
* @throws IOException IO is dangerous
* @throws PGPException OpenPGP is brittle
*/
public static byte[] symmetricallyDecrypt(byte[] data, Passphrase password) throws IOException, PGPException {
public static byte[] symmetricallyDecrypt(@Nonnull byte[] data, @Nonnull Passphrase password)
throws IOException, PGPException {
InputStream in = new BufferedInputStream(new ByteArrayInputStream(data));
in = PGPUtil.getDecoderStream(in);
@ -156,7 +158,7 @@ public class SymmetricEncryptorDecryptor {
* @return compressed data
* @throws IOException IO is dangerous
*/
private static byte[] compress(byte[] clearData, int algorithm) throws IOException {
private static byte[] compress(@Nonnull byte[] clearData, int algorithm) throws IOException {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(algorithm);
OutputStream cos = comData.open(bOut);

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.util;
import javax.annotation.Nonnull;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -52,17 +53,17 @@ public class BCUtil {
/*
PGPXxxKeyRing -> PGPXxxKeyRingCollection
*/
public static PGPPublicKeyRingCollection keyRingsToKeyRingCollection(PGPPublicKeyRing... rings)
public static PGPPublicKeyRingCollection keyRingsToKeyRingCollection(@Nonnull PGPPublicKeyRing... rings)
throws IOException, PGPException {
return new PGPPublicKeyRingCollection(Arrays.asList(rings));
}
public static PGPSecretKeyRingCollection keyRingsToKeyRingCollection(PGPSecretKeyRing... rings)
public static PGPSecretKeyRingCollection keyRingsToKeyRingCollection(@Nonnull PGPSecretKeyRing... rings)
throws IOException, PGPException {
return new PGPSecretKeyRingCollection(Arrays.asList(rings));
}
public static PGPPublicKeyRing publicKeyRingFromSecretKeyRing(PGPSecretKeyRing secretKeys)
public static PGPPublicKeyRing publicKeyRingFromSecretKeyRing(@Nonnull PGPSecretKeyRing secretKeys)
throws PGPException, IOException {
PGPSecretKeyRing fixedSecretKeys = KeyRingSubKeyFix.repairSubkeyPackets(secretKeys, null, null);
@ -81,7 +82,8 @@ public class BCUtil {
PGPXxxKeyRingCollection -> PGPXxxKeyRing
*/
public static PGPSecretKeyRing getKeyRingFromCollection(PGPSecretKeyRingCollection collection, Long id)
public static PGPSecretKeyRing getKeyRingFromCollection(@Nonnull PGPSecretKeyRingCollection collection,
@Nonnull Long id)
throws PGPException {
PGPSecretKeyRing uncleanedRing = collection.getSecretKeyRing(id);
@ -104,27 +106,32 @@ public class BCUtil {
return cleanedRing;
}
public static PGPPublicKeyRing getKeyRingFromCollection(PGPPublicKeyRingCollection collection, Long id)
public static PGPPublicKeyRing getKeyRingFromCollection(@Nonnull PGPPublicKeyRingCollection collection,
@Nonnull Long id)
throws PGPException {
PGPPublicKey key = collection.getPublicKey(id);
return removeUnassociatedKeysFromKeyRing(collection.getPublicKeyRing(id), key);
}
public static InputStream getPgpDecoderInputStream(byte[] bytes) throws IOException {
public static InputStream getPgpDecoderInputStream(@Nonnull byte[] bytes)
throws IOException {
return getPgpDecoderInputStream(new ByteArrayInputStream(bytes));
}
public static InputStream getPgpDecoderInputStream(InputStream inputStream) throws IOException {
public static InputStream getPgpDecoderInputStream(@Nonnull InputStream inputStream)
throws IOException {
return PGPUtil.getDecoderStream(inputStream);
}
public static byte[] getDecodedBytes(byte[] bytes) throws IOException {
public static byte[] getDecodedBytes(@Nonnull byte[] bytes)
throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
Streams.pipeAll(getPgpDecoderInputStream(bytes), buffer);
return buffer.toByteArray();
}
public static byte[] getDecodedBytes(InputStream inputStream) throws IOException {
public static byte[] getDecodedBytes(@Nonnull InputStream inputStream)
throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
Streams.pipeAll(inputStream, buffer);
return getDecodedBytes(buffer.toByteArray());
@ -138,7 +145,8 @@ public class BCUtil {
* @param masterKey master key
* @return "cleaned" key ring
*/
public static PGPPublicKeyRing removeUnassociatedKeysFromKeyRing(PGPPublicKeyRing ring, PGPPublicKey masterKey) {
public static PGPPublicKeyRing removeUnassociatedKeysFromKeyRing(@Nonnull PGPPublicKeyRing ring,
@Nonnull PGPPublicKey masterKey) {
if (!masterKey.isMasterKey()) {
throw new IllegalArgumentException("Given key is not a master key.");
}
@ -168,7 +176,8 @@ public class BCUtil {
* @param masterKey master key
* @return "cleaned" key ring
*/
public static PGPSecretKeyRing removeUnassociatedKeysFromKeyRing(PGPSecretKeyRing ring, PGPPublicKey masterKey) {
public static PGPSecretKeyRing removeUnassociatedKeysFromKeyRing(@Nonnull PGPSecretKeyRing ring,
@Nonnull PGPPublicKey masterKey) {
if (!masterKey.isMasterKey()) {
throw new IllegalArgumentException("Given key is not a master key.");
}
@ -196,7 +205,7 @@ public class BCUtil {
* @param ring key ring
* @return master key
*/
public static PGPPublicKey getMasterKeyFrom(PGPPublicKeyRing ring) {
public static PGPPublicKey getMasterKeyFrom(@Nonnull PGPPublicKeyRing ring) {
Iterator<PGPPublicKey> it = ring.getPublicKeys();
while (it.hasNext()) {
PGPPublicKey k = it.next();
@ -208,7 +217,7 @@ public class BCUtil {
return null;
}
public static PGPPublicKey getMasterKeyFrom(PGPKeyRing ring) {
public static PGPPublicKey getMasterKeyFrom(@Nonnull PGPKeyRing ring) {
Iterator it = ring.getPublicKeys();
while (it.hasNext()) {
PGPPublicKey k = (PGPPublicKey) it.next();
@ -220,7 +229,7 @@ public class BCUtil {
return null;
}
public static Set<Long> signingKeyIds(PGPSecretKeyRing ring) {
public static Set<Long> signingKeyIds(@Nonnull PGPSecretKeyRing ring) {
Set<Long> ids = new HashSet<>();
Iterator<PGPPublicKey> it = ring.getPublicKeys();
while (it.hasNext()) {
@ -261,61 +270,13 @@ public class BCUtil {
return ids;
}
public static boolean keyRingContainsKeyWithId(PGPPublicKeyRing ring, long keyId) {
public static boolean keyRingContainsKeyWithId(@Nonnull PGPPublicKeyRing ring,
long keyId) {
return ring.getPublicKey(keyId) != null;
}
public static boolean keyRingContainsKeyWithId(PGPSecretKeyRing ring, long keyId) {
public static boolean keyRingContainsKeyWithId(@Nonnull PGPSecretKeyRing ring,
long keyId) {
return ring.getSecretKey(keyId) != null;
}
/*
public static PGPKeyRing merge(PGPKeyRing one, PGPKeyRing other) {
PGPPublicKey masterOne = getMasterKeyFrom(one);
if (masterOne == null) {
throw new IllegalArgumentException("First PGPKeyRing has no master key");
}
PGPPublicKey masterOther = getMasterKeyFrom(other);
if (masterOther == null) {
throw new IllegalArgumentException("Other PGPKeyRing has no master key");
}
if (masterOne.getKeyID() != masterOther.getKeyID() ||
Arrays.equals(masterOne.getFingerprint(), masterOther.getFingerprint())) {
throw new IllegalArgumentException("Keys are not the same.");
}
PGPKeyRing merged = one;
boolean mergedIsSecret = (merged instanceof PGPSecretKeyRing);
boolean otherIsSecret = (other instanceof PGPSecretKeyRing);
for (Iterator it = other.getPublicKeys(); it.hasNext(); ) {
PGPPublicKey nextPublicKey = (PGPPublicKey) it.next();
PGPPublicKey pendant = merged.getPublicKey(nextPublicKey.getKeyID());
if (pendant == null) {
if (mergedIsSecret && otherIsSecret) {
// Add secret key
PGPSecretKey secretKey = ((PGPSecretKeyRing) other).getSecretKey(nextPublicKey.getKeyID());
merged = PGPSecretKeyRing.insertSecretKey((PGPSecretKeyRing) merged, secretKey);
} else {
if (mergedIsSecret) {
PGPSecretKeyRing mergedAsSecret = (PGPSecretKeyRing) merged;
PGPSecretKey secretKey = mergedAsSecret.getSecretKey(nextPublicKey.getKeyID());
if (secretKey == null) {
PGPPublicKeyRing mergedAsPublic = publicKeyRingFromSecretKeyRing((PGPSecretKeyRing) merged);
mergedAsPublic = PGPPublicKeyRing.insertPublicKey(mergedAsPublic, nextPublicKey);
mergedAsSecret = PGPSecretKeyRing.replacePublicKeys(mergedAsSecret, mergedAsPublic);
merged = mergedAsSecret;
}
}
}
}
}
}
*/
}

View File

@ -15,6 +15,8 @@
*/
package org.pgpainless.util;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
@ -56,9 +58,9 @@ public class KeyRingSubKeyFix {
*
* @throws PGPException in case we cannot dismantle or reassemble the key.
*/
public static PGPSecretKeyRing repairSubkeyPackets(PGPSecretKeyRing secretKeys,
PBESecretKeyDecryptor decryptor,
PBESecretKeyEncryptor encryptor)
public static PGPSecretKeyRing repairSubkeyPackets(@Nonnull PGPSecretKeyRing secretKeys,
@Nullable PBESecretKeyDecryptor decryptor,
@Nullable PBESecretKeyEncryptor encryptor)
throws PGPException {
PGPDigestCalculator calculator = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1);
@ -68,15 +70,14 @@ public class KeyRingSubKeyFix {
try {
while (secretKeyIterator.hasNext()) {
PGPSecretKey key = secretKeyIterator.next();
PGPSecretKey secSubKey = secretKeyIterator.next();
if (key.isMasterKey()) {
LOGGER.log(Level.INFO, Long.toHexString(key.getKeyID()) + " is master key. Skip.");
_secretKeys.add(key);
if (secSubKey.isMasterKey()) {
LOGGER.log(Level.INFO, Long.toHexString(secSubKey.getKeyID()) + " is master key. Skip.");
_secretKeys.add(secSubKey);
continue;
}
PGPSecretKey secSubKey = key;
PGPPublicKey pubSubKey = secSubKey.getPublicKey();
// check for public key packet type

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.util;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@ -29,14 +30,14 @@ public class MultiMap<K, V> {
map = new HashMap<>();
}
public MultiMap(MultiMap<K, V> other) {
public MultiMap(@Nonnull MultiMap<K, V> other) {
this.map = new HashMap<>();
for (K k : other.map.keySet()) {
map.put(k, new HashSet<>(other.map.get(k)));
}
}
public MultiMap(Map<K, Set<V>> content) {
public MultiMap(@Nonnull Map<K, Set<V>> content) {
this.map = new HashMap<>(content);
}
@ -48,18 +49,18 @@ public class MultiMap<K, V> {
return map.isEmpty();
}
public boolean containsKey(Object o) {
public boolean containsKey(K o) {
return map.containsKey(o);
}
public boolean containsValue(Object o) {
public boolean containsValue(V o) {
for (Set<V> values : map.values()) {
if (values.contains(o)) return true;
}
return false;
}
public Set<V> get(Object o) {
public Set<V> get(K o) {
return map.get(o);
}
@ -78,7 +79,7 @@ public class MultiMap<K, V> {
}
}
public void remove(Object o) {
public void remove(K o) {
for (Set<V> values : map.values()) {
values.remove(o);
}

View File

@ -15,6 +15,7 @@
*/
package org.pgpainless.util;
import javax.annotation.Nullable;
import java.util.Arrays;
public class Passphrase {
@ -29,7 +30,7 @@ public class Passphrase {
*
* @param chars may be null for empty passwords.
*/
public Passphrase(char[] chars) {
public Passphrase(@Nullable char[] chars) {
this.chars = chars;
}
@ -58,12 +59,13 @@ public class Passphrase {
/**
* Return a copy of the underlying char array.
* A return value of {@code null} represents no password.
*
* @return passphrase chars.
*
* @throws IllegalStateException in case the password has been cleared at this point.
*/
public char[] getChars() {
public @Nullable char[] getChars() {
synchronized (lock) {
if (!valid) {
throw new IllegalStateException("Passphrase has been cleared.");
@ -89,4 +91,13 @@ public class Passphrase {
return valid;
}
}
/**
* Represents a {@link Passphrase} instance that represents no password.
*
* @return empty passphrase
*/
public static Passphrase emptyPassphrase() {
return new Passphrase(null);
}
}