1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-26 06:12:06 +01:00

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:bcprov-jdk15on:1.60'
//*/ //*/
compile 'org.bouncycastle:bcpg-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; package org.pgpainless;
import javax.annotation.Nonnull;
import java.io.IOException;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.pgpainless.algorithm.CompressionAlgorithm; import org.pgpainless.algorithm.CompressionAlgorithm;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm; import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
@ -27,8 +30,6 @@ import org.pgpainless.key.parsing.KeyRingReader;
import org.pgpainless.symmetric_encryption.SymmetricEncryptorDecryptor; import org.pgpainless.symmetric_encryption.SymmetricEncryptorDecryptor;
import org.pgpainless.util.Passphrase; import org.pgpainless.util.Passphrase;
import java.io.IOException;
public class PGPainless { public class PGPainless {
/** /**
@ -73,7 +74,7 @@ public class PGPainless {
* @throws IOException IO is dangerous. * @throws IOException IO is dangerous.
* @throws PGPException PGP is brittle. * @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, return SymmetricEncryptorDecryptor.symmetricallyEncrypt(data, password,
algorithm, CompressionAlgorithm.UNCOMPRESSED); algorithm, CompressionAlgorithm.UNCOMPRESSED);
} }
@ -88,7 +89,7 @@ public class PGPainless {
* @throws IOException IO is dangerous. * @throws IOException IO is dangerous.
* @throws PGPException PGP is brittle. * @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); return SymmetricEncryptorDecryptor.symmetricallyDecrypt(data, password);
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -15,6 +15,8 @@
*/ */
package org.pgpainless.decryption_verification; package org.pgpainless.decryption_verification;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKey;
public interface MissingPublicKeyCallback { public interface MissingPublicKeyCallback {
@ -29,6 +31,6 @@ public interface MissingPublicKeyCallback {
* *
* @return the key or null * @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; package org.pgpainless.decryption_verification;
import javax.annotation.Nonnull;
import java.io.FilterInputStream; import java.io.FilterInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -41,10 +42,10 @@ public class SignatureVerifyingInputStream extends FilterInputStream {
private boolean validated = false; private boolean validated = false;
protected SignatureVerifyingInputStream(InputStream inputStream, protected SignatureVerifyingInputStream(@Nonnull InputStream inputStream,
PGPObjectFactory objectFactory, @Nonnull PGPObjectFactory objectFactory,
Map<OpenPgpV4Fingerprint, PGPOnePassSignature> onePassSignatures, @Nonnull Map<OpenPgpV4Fingerprint, PGPOnePassSignature> onePassSignatures,
OpenPgpMetadata.Builder resultBuilder) { @Nonnull OpenPgpMetadata.Builder resultBuilder) {
super(inputStream); super(inputStream);
this.objectFactory = objectFactory; this.objectFactory = objectFactory;
this.resultBuilder = resultBuilder; this.resultBuilder = resultBuilder;

View file

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

View file

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

View file

@ -15,6 +15,7 @@
*/ */
package org.pgpainless.encryption_signing; package org.pgpainless.encryption_signing;
import javax.annotation.Nonnull;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
@ -75,13 +76,13 @@ public final class EncryptionStream extends OutputStream {
private PGPLiteralDataGenerator literalDataGenerator; private PGPLiteralDataGenerator literalDataGenerator;
private OutputStream literalDataStream; private OutputStream literalDataStream;
private EncryptionStream(OutputStream targetOutputStream, EncryptionStream(@Nonnull OutputStream targetOutputStream,
Set<PGPPublicKey> encryptionKeys, @Nonnull Set<PGPPublicKey> encryptionKeys,
Set<PGPPrivateKey> signingKeys, @Nonnull Set<PGPPrivateKey> signingKeys,
SymmetricKeyAlgorithm symmetricKeyAlgorithm, @Nonnull SymmetricKeyAlgorithm symmetricKeyAlgorithm,
HashAlgorithm hashAlgorithm, @Nonnull HashAlgorithm hashAlgorithm,
CompressionAlgorithm compressionAlgorithm, @Nonnull CompressionAlgorithm compressionAlgorithm,
boolean asciiArmor) boolean asciiArmor)
throws IOException, PGPException { throws IOException, PGPException {
// Currently outermost Stream // Currently outermost Stream
@ -163,31 +164,6 @@ public final class EncryptionStream extends OutputStream {
signingKeyIds, Collections.emptySet()); 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 @Override
public void write(int data) throws IOException { public void write(int data) throws IOException {
literalDataStream.write(data); 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() { public OpenPgpMetadata getResult() {
return result; 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; package org.pgpainless.key;
import javax.annotation.Nonnull;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.Charset; 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> * XEP-0373 §4.1: The OpenPGP Public-Key Data Node about how to obtain the fingerprint</a>
* @param fingerprint hexadecimal representation of the fingerprint. * @param fingerprint hexadecimal representation of the fingerprint.
*/ */
public OpenPgpV4Fingerprint(String fingerprint) { public OpenPgpV4Fingerprint(@Nonnull String fingerprint) {
if (fingerprint == null) {
throw new NullPointerException("Fingerprint MUST NOT be null.");
}
String fp = fingerprint.trim().toUpperCase(); String fp = fingerprint.trim().toUpperCase();
if (!isValid(fp)) { if (!isValid(fp)) {
throw new IllegalArgumentException("Fingerprint " + fingerprint + throw new IllegalArgumentException("Fingerprint " + fingerprint +
@ -51,26 +49,26 @@ public class OpenPgpV4Fingerprint implements CharSequence, Comparable<OpenPgpV4F
this.fingerprint = fp; this.fingerprint = fp;
} }
public OpenPgpV4Fingerprint(byte[] bytes) { public OpenPgpV4Fingerprint(@Nonnull byte[] bytes) {
this(new String(bytes, Charset.forName("UTF-8"))); this(new String(bytes, Charset.forName("UTF-8")));
} }
public OpenPgpV4Fingerprint(PGPPublicKey key) { public OpenPgpV4Fingerprint(@Nonnull PGPPublicKey key) {
this(Hex.encode(key.getFingerprint())); this(Hex.encode(key.getFingerprint()));
if (key.getVersion() != 4) { if (key.getVersion() != 4) {
throw new IllegalArgumentException("Key is not a v4 OpenPgp key."); throw new IllegalArgumentException("Key is not a v4 OpenPgp key.");
} }
} }
public OpenPgpV4Fingerprint(PGPSecretKey key) { public OpenPgpV4Fingerprint(@Nonnull PGPSecretKey key) {
this(key.getPublicKey()); this(key.getPublicKey());
} }
public OpenPgpV4Fingerprint(PGPPublicKeyRing ring) { public OpenPgpV4Fingerprint(@Nonnull PGPPublicKeyRing ring) {
this(ring.getPublicKey()); this(ring.getPublicKey());
} }
public OpenPgpV4Fingerprint(PGPSecretKeyRing ring) { public OpenPgpV4Fingerprint(@Nonnull PGPSecretKeyRing ring) {
this(ring.getPublicKey()); this(ring.getPublicKey());
} }
@ -79,7 +77,7 @@ public class OpenPgpV4Fingerprint implements CharSequence, Comparable<OpenPgpV4F
* @param fp fingerprint to check. * @param fp fingerprint to check.
* @return true if fingerprint is valid. * @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}"); return fp.matches("[0-9A-F]{40}");
} }
@ -143,7 +141,7 @@ public class OpenPgpV4Fingerprint implements CharSequence, Comparable<OpenPgpV4F
} }
@Override @Override
public int compareTo(OpenPgpV4Fingerprint openPgpV4Fingerprint) { public int compareTo(@Nonnull OpenPgpV4Fingerprint openPgpV4Fingerprint) {
return fingerprint.compareTo(openPgpV4Fingerprint.fingerprint); return fingerprint.compareTo(openPgpV4Fingerprint.fingerprint);
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -15,6 +15,8 @@
*/ */
package org.pgpainless.key.protection; package org.pgpainless.key.protection;
import javax.annotation.Nullable;
import org.pgpainless.util.Passphrase; import org.pgpainless.util.Passphrase;
/** /**
@ -23,10 +25,12 @@ import org.pgpainless.util.Passphrase;
public interface SecretKeyPassphraseProvider { 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 * @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; package org.pgpainless.key.protection;
import javax.annotation.Nullable;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
@ -23,19 +25,21 @@ public interface SecretKeyRingProtector {
/** /**
* Return a decryptor for the key of id {@code keyId}. * 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 * @param keyId id of the key
* @return decryptor for 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}. * 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 * @param keyId id of the key
* @return encryptor for the key * @return encryptor for the key
* @throws PGPException if the encryptor cannot be created for some reason * @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; package org.pgpainless.key.protection;
import javax.annotation.Nullable;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; 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. * Implementation of the {@link SecretKeyRingProtector} which assumes that all handled keys are not password protected.
*/ */
public class UnprotectedKeysProtector implements SecretKeyRingProtector { public class UnprotectedKeysProtector implements SecretKeyRingProtector {
@Override @Override
@Nullable
public PBESecretKeyDecryptor getDecryptor(Long keyId) { public PBESecretKeyDecryptor getDecryptor(Long keyId) {
return null; return null;
} }
@Override @Override
@Nullable
public PBESecretKeyEncryptor getEncryptor(Long keyId) { public PBESecretKeyEncryptor getEncryptor(Long keyId) {
return null; return null;
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -15,6 +15,7 @@
*/ */
package org.pgpainless.util; package org.pgpainless.util;
import javax.annotation.Nonnull;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@ -52,17 +53,17 @@ public class BCUtil {
/* /*
PGPXxxKeyRing -> PGPXxxKeyRingCollection PGPXxxKeyRing -> PGPXxxKeyRingCollection
*/ */
public static PGPPublicKeyRingCollection keyRingsToKeyRingCollection(PGPPublicKeyRing... rings) public static PGPPublicKeyRingCollection keyRingsToKeyRingCollection(@Nonnull PGPPublicKeyRing... rings)
throws IOException, PGPException { throws IOException, PGPException {
return new PGPPublicKeyRingCollection(Arrays.asList(rings)); return new PGPPublicKeyRingCollection(Arrays.asList(rings));
} }
public static PGPSecretKeyRingCollection keyRingsToKeyRingCollection(PGPSecretKeyRing... rings) public static PGPSecretKeyRingCollection keyRingsToKeyRingCollection(@Nonnull PGPSecretKeyRing... rings)
throws IOException, PGPException { throws IOException, PGPException {
return new PGPSecretKeyRingCollection(Arrays.asList(rings)); return new PGPSecretKeyRingCollection(Arrays.asList(rings));
} }
public static PGPPublicKeyRing publicKeyRingFromSecretKeyRing(PGPSecretKeyRing secretKeys) public static PGPPublicKeyRing publicKeyRingFromSecretKeyRing(@Nonnull PGPSecretKeyRing secretKeys)
throws PGPException, IOException { throws PGPException, IOException {
PGPSecretKeyRing fixedSecretKeys = KeyRingSubKeyFix.repairSubkeyPackets(secretKeys, null, null); PGPSecretKeyRing fixedSecretKeys = KeyRingSubKeyFix.repairSubkeyPackets(secretKeys, null, null);
@ -81,7 +82,8 @@ public class BCUtil {
PGPXxxKeyRingCollection -> PGPXxxKeyRing PGPXxxKeyRingCollection -> PGPXxxKeyRing
*/ */
public static PGPSecretKeyRing getKeyRingFromCollection(PGPSecretKeyRingCollection collection, Long id) public static PGPSecretKeyRing getKeyRingFromCollection(@Nonnull PGPSecretKeyRingCollection collection,
@Nonnull Long id)
throws PGPException { throws PGPException {
PGPSecretKeyRing uncleanedRing = collection.getSecretKeyRing(id); PGPSecretKeyRing uncleanedRing = collection.getSecretKeyRing(id);
@ -104,27 +106,32 @@ public class BCUtil {
return cleanedRing; return cleanedRing;
} }
public static PGPPublicKeyRing getKeyRingFromCollection(PGPPublicKeyRingCollection collection, Long id) public static PGPPublicKeyRing getKeyRingFromCollection(@Nonnull PGPPublicKeyRingCollection collection,
@Nonnull Long id)
throws PGPException { throws PGPException {
PGPPublicKey key = collection.getPublicKey(id); PGPPublicKey key = collection.getPublicKey(id);
return removeUnassociatedKeysFromKeyRing(collection.getPublicKeyRing(id), key); 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)); 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); 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(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
Streams.pipeAll(getPgpDecoderInputStream(bytes), buffer); Streams.pipeAll(getPgpDecoderInputStream(bytes), buffer);
return buffer.toByteArray(); return buffer.toByteArray();
} }
public static byte[] getDecodedBytes(InputStream inputStream) throws IOException { public static byte[] getDecodedBytes(@Nonnull InputStream inputStream)
throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ByteArrayOutputStream buffer = new ByteArrayOutputStream();
Streams.pipeAll(inputStream, buffer); Streams.pipeAll(inputStream, buffer);
return getDecodedBytes(buffer.toByteArray()); return getDecodedBytes(buffer.toByteArray());
@ -138,7 +145,8 @@ public class BCUtil {
* @param masterKey master key * @param masterKey master key
* @return "cleaned" key ring * @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()) { if (!masterKey.isMasterKey()) {
throw new IllegalArgumentException("Given key is not a master key."); throw new IllegalArgumentException("Given key is not a master key.");
} }
@ -168,7 +176,8 @@ public class BCUtil {
* @param masterKey master key * @param masterKey master key
* @return "cleaned" key ring * @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()) { if (!masterKey.isMasterKey()) {
throw new IllegalArgumentException("Given key is not a master key."); throw new IllegalArgumentException("Given key is not a master key.");
} }
@ -196,7 +205,7 @@ public class BCUtil {
* @param ring key ring * @param ring key ring
* @return master key * @return master key
*/ */
public static PGPPublicKey getMasterKeyFrom(PGPPublicKeyRing ring) { public static PGPPublicKey getMasterKeyFrom(@Nonnull PGPPublicKeyRing ring) {
Iterator<PGPPublicKey> it = ring.getPublicKeys(); Iterator<PGPPublicKey> it = ring.getPublicKeys();
while (it.hasNext()) { while (it.hasNext()) {
PGPPublicKey k = it.next(); PGPPublicKey k = it.next();
@ -208,7 +217,7 @@ public class BCUtil {
return null; return null;
} }
public static PGPPublicKey getMasterKeyFrom(PGPKeyRing ring) { public static PGPPublicKey getMasterKeyFrom(@Nonnull PGPKeyRing ring) {
Iterator it = ring.getPublicKeys(); Iterator it = ring.getPublicKeys();
while (it.hasNext()) { while (it.hasNext()) {
PGPPublicKey k = (PGPPublicKey) it.next(); PGPPublicKey k = (PGPPublicKey) it.next();
@ -220,7 +229,7 @@ public class BCUtil {
return null; return null;
} }
public static Set<Long> signingKeyIds(PGPSecretKeyRing ring) { public static Set<Long> signingKeyIds(@Nonnull PGPSecretKeyRing ring) {
Set<Long> ids = new HashSet<>(); Set<Long> ids = new HashSet<>();
Iterator<PGPPublicKey> it = ring.getPublicKeys(); Iterator<PGPPublicKey> it = ring.getPublicKeys();
while (it.hasNext()) { while (it.hasNext()) {
@ -261,61 +270,13 @@ public class BCUtil {
return ids; return ids;
} }
public static boolean keyRingContainsKeyWithId(PGPPublicKeyRing ring, long keyId) { public static boolean keyRingContainsKeyWithId(@Nonnull PGPPublicKeyRing ring,
long keyId) {
return ring.getPublicKey(keyId) != null; 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; 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; package org.pgpainless.util;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
@ -56,9 +58,9 @@ public class KeyRingSubKeyFix {
* *
* @throws PGPException in case we cannot dismantle or reassemble the key. * @throws PGPException in case we cannot dismantle or reassemble the key.
*/ */
public static PGPSecretKeyRing repairSubkeyPackets(PGPSecretKeyRing secretKeys, public static PGPSecretKeyRing repairSubkeyPackets(@Nonnull PGPSecretKeyRing secretKeys,
PBESecretKeyDecryptor decryptor, @Nullable PBESecretKeyDecryptor decryptor,
PBESecretKeyEncryptor encryptor) @Nullable PBESecretKeyEncryptor encryptor)
throws PGPException { throws PGPException {
PGPDigestCalculator calculator = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); PGPDigestCalculator calculator = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1);
@ -68,15 +70,14 @@ public class KeyRingSubKeyFix {
try { try {
while (secretKeyIterator.hasNext()) { while (secretKeyIterator.hasNext()) {
PGPSecretKey key = secretKeyIterator.next(); PGPSecretKey secSubKey = secretKeyIterator.next();
if (key.isMasterKey()) { if (secSubKey.isMasterKey()) {
LOGGER.log(Level.INFO, Long.toHexString(key.getKeyID()) + " is master key. Skip."); LOGGER.log(Level.INFO, Long.toHexString(secSubKey.getKeyID()) + " is master key. Skip.");
_secretKeys.add(key); _secretKeys.add(secSubKey);
continue; continue;
} }
PGPSecretKey secSubKey = key;
PGPPublicKey pubSubKey = secSubKey.getPublicKey(); PGPPublicKey pubSubKey = secSubKey.getPublicKey();
// check for public key packet type // check for public key packet type

View file

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

View file

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