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