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:
parent
51991bdb07
commit
b89d3562ac
53 changed files with 387 additions and 370 deletions
|
@ -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'
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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 + ">";
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue