mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-23 04:42:06 +01:00
Allow specification of signature type
This commit is contained in:
parent
aeed8bf705
commit
4870bda4f2
6 changed files with 47 additions and 15 deletions
|
@ -35,6 +35,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
|
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
|
||||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
import org.pgpainless.algorithm.HashAlgorithm;
|
import org.pgpainless.algorithm.HashAlgorithm;
|
||||||
|
import org.pgpainless.algorithm.SignatureType;
|
||||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
import org.pgpainless.exception.SecretKeyNotFoundException;
|
import org.pgpainless.exception.SecretKeyNotFoundException;
|
||||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
@ -54,6 +55,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
private OutputStream outputStream;
|
private OutputStream outputStream;
|
||||||
private final Set<PGPPublicKey> encryptionKeys = new HashSet<>();
|
private final Set<PGPPublicKey> encryptionKeys = new HashSet<>();
|
||||||
private boolean detachedSignature = false;
|
private boolean detachedSignature = false;
|
||||||
|
private SignatureType signatureType = SignatureType.BINARY_DOCUMENT;
|
||||||
private final Set<PGPSecretKey> signingKeys = new HashSet<>();
|
private final Set<PGPSecretKey> signingKeys = new HashSet<>();
|
||||||
private SecretKeyRingProtector signingKeysDecryptor;
|
private SecretKeyRingProtector signingKeysDecryptor;
|
||||||
private SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm.AES_128;
|
private SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm.AES_128;
|
||||||
|
@ -257,17 +259,17 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Armor signWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKey... keys) {
|
public DocumentType signWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKey... keys) {
|
||||||
return new SignWithImpl().signWith(decryptor, keys);
|
return new SignWithImpl().signWith(decryptor, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Armor signWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRing... keyRings) {
|
public DocumentType signWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRing... keyRings) {
|
||||||
return new SignWithImpl().signWith(decryptor, keyRings);
|
return new SignWithImpl().signWith(decryptor, keyRings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <O> Armor signWith(@Nonnull SecretKeyRingSelectionStrategy<O> selectionStrategy,
|
public <O> DocumentType signWith(@Nonnull SecretKeyRingSelectionStrategy<O> selectionStrategy,
|
||||||
@Nonnull SecretKeyRingProtector decryptor,
|
@Nonnull SecretKeyRingProtector decryptor,
|
||||||
@Nonnull MultiMap<O, PGPSecretKeyRingCollection> keys)
|
@Nonnull MultiMap<O, PGPSecretKeyRingCollection> keys)
|
||||||
throws SecretKeyNotFoundException {
|
throws SecretKeyNotFoundException {
|
||||||
|
@ -278,7 +280,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
class SignWithImpl implements SignWith {
|
class SignWithImpl implements SignWith {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Armor signWith(@Nonnull SecretKeyRingProtector decryptor,
|
public DocumentType signWith(@Nonnull SecretKeyRingProtector decryptor,
|
||||||
@Nonnull PGPSecretKey... keys) {
|
@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.");
|
||||||
|
@ -291,11 +293,11 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EncryptionBuilder.this.signingKeysDecryptor = decryptor;
|
EncryptionBuilder.this.signingKeysDecryptor = decryptor;
|
||||||
return new ArmorImpl();
|
return new DocumentTypeImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Armor signWith(@Nonnull SecretKeyRingProtector decryptor,
|
public DocumentType signWith(@Nonnull SecretKeyRingProtector decryptor,
|
||||||
@Nonnull PGPSecretKeyRing... keys) {
|
@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.");
|
||||||
|
@ -309,11 +311,11 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EncryptionBuilder.this.signingKeysDecryptor = decryptor;
|
EncryptionBuilder.this.signingKeysDecryptor = decryptor;
|
||||||
return new ArmorImpl();
|
return new DocumentTypeImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <O> Armor signWith(@Nonnull SecretKeyRingSelectionStrategy<O> ringSelectionStrategy,
|
public <O> DocumentType signWith(@Nonnull SecretKeyRingSelectionStrategy<O> ringSelectionStrategy,
|
||||||
@Nonnull SecretKeyRingProtector decryptor,
|
@Nonnull SecretKeyRingProtector decryptor,
|
||||||
@Nonnull MultiMap<O, PGPSecretKeyRingCollection> keys) {
|
@Nonnull MultiMap<O, PGPSecretKeyRingCollection> keys) {
|
||||||
if (keys.isEmpty()) {
|
if (keys.isEmpty()) {
|
||||||
|
@ -332,6 +334,21 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return new DocumentTypeImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DocumentTypeImpl implements DocumentType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Armor signBinaryDocument() {
|
||||||
|
EncryptionBuilder.this.signatureType = SignatureType.BINARY_DOCUMENT;
|
||||||
|
return new ArmorImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Armor signCanonicalText() {
|
||||||
|
EncryptionBuilder.this.signatureType = SignatureType.CANONICAL_TEXT_DOCUMENT;
|
||||||
return new ArmorImpl();
|
return new ArmorImpl();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,6 +380,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
EncryptionBuilder.this.outputStream,
|
EncryptionBuilder.this.outputStream,
|
||||||
EncryptionBuilder.this.encryptionKeys,
|
EncryptionBuilder.this.encryptionKeys,
|
||||||
EncryptionBuilder.this.detachedSignature,
|
EncryptionBuilder.this.detachedSignature,
|
||||||
|
signatureType,
|
||||||
privateKeys,
|
privateKeys,
|
||||||
EncryptionBuilder.this.symmetricKeyAlgorithm,
|
EncryptionBuilder.this.symmetricKeyAlgorithm,
|
||||||
EncryptionBuilder.this.hashAlgorithm,
|
EncryptionBuilder.this.hashAlgorithm,
|
||||||
|
|
|
@ -181,7 +181,7 @@ public interface EncryptionBuilderInterface {
|
||||||
* @param keys secret keys
|
* @param keys secret keys
|
||||||
* @return api handle
|
* @return api handle
|
||||||
*/
|
*/
|
||||||
default Armor signWith(@Nonnull PGPSecretKey... keys) {
|
default DocumentType signWith(@Nonnull PGPSecretKey... keys) {
|
||||||
return signWith(new UnprotectedKeysProtector(), keys);
|
return signWith(new UnprotectedKeysProtector(), keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ public interface EncryptionBuilderInterface {
|
||||||
* @param keys secret keys used for signing
|
* @param keys secret keys used for signing
|
||||||
* @return api handle
|
* @return api handle
|
||||||
*/
|
*/
|
||||||
Armor signWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKey... keys);
|
DocumentType signWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKey... keys);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass in a list of secret keys used for signing, along with a {@link SecretKeyRingProtector} used to unlock
|
* Pass in a list of secret keys used for signing, along with a {@link SecretKeyRingProtector} used to unlock
|
||||||
|
@ -203,7 +203,7 @@ public interface EncryptionBuilderInterface {
|
||||||
* @param keyRings secret keys used for signing
|
* @param keyRings secret keys used for signing
|
||||||
* @return api handle
|
* @return api handle
|
||||||
*/
|
*/
|
||||||
Armor signWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRing... keyRings);
|
DocumentType signWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRing... keyRings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass in a map of secret keys for signing, as well as a {@link org.pgpainless.key.selection.key.SecretKeySelectionStrategy}
|
* Pass in a map of secret keys for signing, as well as a {@link org.pgpainless.key.selection.key.SecretKeySelectionStrategy}
|
||||||
|
@ -218,13 +218,20 @@ public interface EncryptionBuilderInterface {
|
||||||
*
|
*
|
||||||
* @throws SecretKeyNotFoundException in case no suitable secret key can be found
|
* @throws SecretKeyNotFoundException in case no suitable secret key can be found
|
||||||
*/
|
*/
|
||||||
<O> Armor signWith(@Nonnull SecretKeyRingSelectionStrategy<O> selectionStrategy,
|
<O> DocumentType signWith(@Nonnull SecretKeyRingSelectionStrategy<O> selectionStrategy,
|
||||||
@Nonnull SecretKeyRingProtector decryptor,
|
@Nonnull SecretKeyRingProtector decryptor,
|
||||||
@Nonnull MultiMap<O, PGPSecretKeyRingCollection> keys)
|
@Nonnull MultiMap<O, PGPSecretKeyRingCollection> keys)
|
||||||
throws SecretKeyNotFoundException;
|
throws SecretKeyNotFoundException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DocumentType {
|
||||||
|
|
||||||
|
Armor signBinaryDocument();
|
||||||
|
|
||||||
|
Armor signCanonicalText();
|
||||||
|
}
|
||||||
|
|
||||||
interface Armor {
|
interface Armor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder;
|
||||||
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
|
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
|
||||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
import org.pgpainless.algorithm.HashAlgorithm;
|
import org.pgpainless.algorithm.HashAlgorithm;
|
||||||
|
import org.pgpainless.algorithm.SignatureType;
|
||||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
import org.pgpainless.decryption_verification.DetachedSignature;
|
import org.pgpainless.decryption_verification.DetachedSignature;
|
||||||
import org.pgpainless.decryption_verification.OpenPgpMetadata;
|
import org.pgpainless.decryption_verification.OpenPgpMetadata;
|
||||||
|
@ -63,6 +64,7 @@ public final class EncryptionStream extends OutputStream {
|
||||||
private final CompressionAlgorithm compressionAlgorithm;
|
private final CompressionAlgorithm compressionAlgorithm;
|
||||||
private final Set<PGPPublicKey> encryptionKeys;
|
private final Set<PGPPublicKey> encryptionKeys;
|
||||||
private final boolean detachedSignature;
|
private final boolean detachedSignature;
|
||||||
|
private final SignatureType signatureType;
|
||||||
private final Map<OpenPgpV4Fingerprint, PGPPrivateKey> signingKeys;
|
private final Map<OpenPgpV4Fingerprint, PGPPrivateKey> signingKeys;
|
||||||
private final boolean asciiArmor;
|
private final boolean asciiArmor;
|
||||||
|
|
||||||
|
@ -85,6 +87,7 @@ public final class EncryptionStream extends OutputStream {
|
||||||
EncryptionStream(@Nonnull OutputStream targetOutputStream,
|
EncryptionStream(@Nonnull OutputStream targetOutputStream,
|
||||||
@Nonnull Set<PGPPublicKey> encryptionKeys,
|
@Nonnull Set<PGPPublicKey> encryptionKeys,
|
||||||
boolean detachedSignature,
|
boolean detachedSignature,
|
||||||
|
SignatureType signatureType,
|
||||||
@Nonnull Map<OpenPgpV4Fingerprint, PGPPrivateKey> signingKeys,
|
@Nonnull Map<OpenPgpV4Fingerprint, PGPPrivateKey> signingKeys,
|
||||||
@Nonnull SymmetricKeyAlgorithm symmetricKeyAlgorithm,
|
@Nonnull SymmetricKeyAlgorithm symmetricKeyAlgorithm,
|
||||||
@Nonnull HashAlgorithm hashAlgorithm,
|
@Nonnull HashAlgorithm hashAlgorithm,
|
||||||
|
@ -97,6 +100,7 @@ public final class EncryptionStream extends OutputStream {
|
||||||
this.compressionAlgorithm = compressionAlgorithm;
|
this.compressionAlgorithm = compressionAlgorithm;
|
||||||
this.encryptionKeys = Collections.unmodifiableSet(encryptionKeys);
|
this.encryptionKeys = Collections.unmodifiableSet(encryptionKeys);
|
||||||
this.detachedSignature = detachedSignature;
|
this.detachedSignature = detachedSignature;
|
||||||
|
this.signatureType = signatureType;
|
||||||
this.signingKeys = Collections.unmodifiableMap(signingKeys);
|
this.signingKeys = Collections.unmodifiableMap(signingKeys);
|
||||||
this.asciiArmor = asciiArmor;
|
this.asciiArmor = asciiArmor;
|
||||||
|
|
||||||
|
@ -156,7 +160,7 @@ public final class EncryptionStream extends OutputStream {
|
||||||
privateKey.getPublicKeyPacket().getAlgorithm(), hashAlgorithm.getAlgorithmId());
|
privateKey.getPublicKeyPacket().getAlgorithm(), hashAlgorithm.getAlgorithmId());
|
||||||
|
|
||||||
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
|
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(contentSignerBuilder);
|
||||||
signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
|
signatureGenerator.init(signatureType.getCode(), privateKey);
|
||||||
signatureGenerators.put(fingerprint, signatureGenerator);
|
signatureGenerators.put(fingerprint, signatureGenerator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,7 @@ public class EncryptDecryptTest {
|
||||||
.toRecipients(recipientPub)
|
.toRecipients(recipientPub)
|
||||||
.usingSecureAlgorithms()
|
.usingSecureAlgorithms()
|
||||||
.signWith(keyDecryptor, senderSec)
|
.signWith(keyDecryptor, senderSec)
|
||||||
|
.signBinaryDocument()
|
||||||
.noArmor();
|
.noArmor();
|
||||||
|
|
||||||
Streams.pipeAll(new ByteArrayInputStream(secretMessage), encryptor);
|
Streams.pipeAll(new ByteArrayInputStream(secretMessage), encryptor);
|
||||||
|
@ -197,6 +198,7 @@ public class EncryptDecryptTest {
|
||||||
.doNotEncrypt()
|
.doNotEncrypt()
|
||||||
.createDetachedSignature()
|
.createDetachedSignature()
|
||||||
.signWith(keyRingProtector, signingKeys)
|
.signWith(keyRingProtector, signingKeys)
|
||||||
|
.signBinaryDocument()
|
||||||
.noArmor();
|
.noArmor();
|
||||||
Streams.pipeAll(inputStream, signer);
|
Streams.pipeAll(inputStream, signer);
|
||||||
signer.close();
|
signer.close();
|
||||||
|
@ -238,6 +240,7 @@ public class EncryptDecryptTest {
|
||||||
EncryptionStream signer = PGPainless.encryptAndOrSign().onOutputStream(signOut)
|
EncryptionStream signer = PGPainless.encryptAndOrSign().onOutputStream(signOut)
|
||||||
.doNotEncrypt()
|
.doNotEncrypt()
|
||||||
.signWith(keyRingProtector, signingKeys)
|
.signWith(keyRingProtector, signingKeys)
|
||||||
|
.signBinaryDocument()
|
||||||
.asciiArmor();
|
.asciiArmor();
|
||||||
Streams.pipeAll(inputStream, signer);
|
Streams.pipeAll(inputStream, signer);
|
||||||
signer.close();
|
signer.close();
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.util.Random;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import jdk.nashorn.internal.ir.annotations.Ignore;
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
@ -96,7 +95,6 @@ public class LengthTest {
|
||||||
encryptDecryptForSecretKeyRings(sender, recipient);
|
encryptDecryptForSecretKeyRings(sender, recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
private void encryptDecryptForSecretKeyRings(PGPSecretKeyRing senderSec, PGPSecretKeyRing recipientSec)
|
private void encryptDecryptForSecretKeyRings(PGPSecretKeyRing senderSec, PGPSecretKeyRing recipientSec)
|
||||||
throws PGPException,
|
throws PGPException,
|
||||||
IOException {
|
IOException {
|
||||||
|
@ -117,6 +115,7 @@ public class LengthTest {
|
||||||
// .doNotEncrypt()
|
// .doNotEncrypt()
|
||||||
.usingSecureAlgorithms()
|
.usingSecureAlgorithms()
|
||||||
.signWith(keyDecryptor, senderSec)
|
.signWith(keyDecryptor, senderSec)
|
||||||
|
.signBinaryDocument()
|
||||||
.noArmor();
|
.noArmor();
|
||||||
|
|
||||||
Streams.pipeAll(new ByteArrayInputStream(secretMessage), encryptor);
|
Streams.pipeAll(new ByteArrayInputStream(secretMessage), encryptor);
|
||||||
|
|
|
@ -182,6 +182,7 @@ public class ChangeSecretKeyRingPassphraseTest {
|
||||||
EncryptionStream stream = PGPainless.encryptAndOrSign().onOutputStream(dummy)
|
EncryptionStream stream = PGPainless.encryptAndOrSign().onOutputStream(dummy)
|
||||||
.doNotEncrypt()
|
.doNotEncrypt()
|
||||||
.signWith(PasswordBasedSecretKeyRingProtector.forKey(keyRing, passphrase), keyRing)
|
.signWith(PasswordBasedSecretKeyRingProtector.forKey(keyRing, passphrase), keyRing)
|
||||||
|
.signBinaryDocument()
|
||||||
.noArmor();
|
.noArmor();
|
||||||
|
|
||||||
Streams.pipeAll(new ByteArrayInputStream(dummyMessage.getBytes()), stream);
|
Streams.pipeAll(new ByteArrayInputStream(dummyMessage.getBytes()), stream);
|
||||||
|
|
Loading…
Reference in a new issue