mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-10-31 17:45:58 +01:00
Hide distinction between clearsigned and inline signed message verification
This commit is contained in:
parent
bd67d9c0fa
commit
59c9ec341e
9 changed files with 69 additions and 115 deletions
|
@ -22,8 +22,6 @@ import org.pgpainless.key.modification.secretkeyring.SecretKeyRingEditorInterfac
|
||||||
import org.pgpainless.key.parsing.KeyRingReader;
|
import org.pgpainless.key.parsing.KeyRingReader;
|
||||||
import org.pgpainless.key.util.KeyRingUtils;
|
import org.pgpainless.key.util.KeyRingUtils;
|
||||||
import org.pgpainless.policy.Policy;
|
import org.pgpainless.policy.Policy;
|
||||||
import org.pgpainless.decryption_verification.cleartext_signatures.VerifyCleartextSignatures;
|
|
||||||
import org.pgpainless.decryption_verification.cleartext_signatures.VerifyCleartextSignaturesImpl;
|
|
||||||
import org.pgpainless.util.ArmorUtils;
|
import org.pgpainless.util.ArmorUtils;
|
||||||
|
|
||||||
public final class PGPainless {
|
public final class PGPainless {
|
||||||
|
@ -91,26 +89,6 @@ public final class PGPainless {
|
||||||
return new DecryptionBuilder();
|
return new DecryptionBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify a cleartext-signed message.
|
|
||||||
* Cleartext signed messages are often found in emails and look like this:
|
|
||||||
* <pre>
|
|
||||||
* {@code
|
|
||||||
* -----BEGIN PGP SIGNED MESSAGE-----
|
|
||||||
* Hash: [Hash algorithm]
|
|
||||||
* [Human Readable Message Body]
|
|
||||||
* -----BEGIN PGP SIGNATURE-----
|
|
||||||
* [Signature]
|
|
||||||
* -----END PGP SIGNATURE-----
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @return builder
|
|
||||||
*/
|
|
||||||
public static VerifyCleartextSignatures verifyCleartextSignedMessage() {
|
|
||||||
return new VerifyCleartextSignaturesImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make changes to a key ring.
|
* Make changes to a key ring.
|
||||||
* This method can be used to change key expiration dates and passphrases, or add/remove/revoke subkeys.
|
* This method can be used to change key expiration dates and passphrases, or add/remove/revoke subkeys.
|
||||||
|
|
|
@ -22,6 +22,8 @@ import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
import org.bouncycastle.openpgp.PGPSignature;
|
import org.bouncycastle.openpgp.PGPSignature;
|
||||||
|
import org.pgpainless.decryption_verification.cleartext_signatures.InMemoryMultiPassStrategy;
|
||||||
|
import org.pgpainless.decryption_verification.cleartext_signatures.MultiPassStrategy;
|
||||||
import org.pgpainless.exception.NotYetImplementedException;
|
import org.pgpainless.exception.NotYetImplementedException;
|
||||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
import org.pgpainless.signature.SignatureUtils;
|
import org.pgpainless.signature.SignatureUtils;
|
||||||
|
@ -50,6 +52,7 @@ public class ConsumerOptions {
|
||||||
private final Set<Passphrase> decryptionPassphrases = new HashSet<>();
|
private final Set<Passphrase> decryptionPassphrases = new HashSet<>();
|
||||||
private MissingKeyPassphraseStrategy missingKeyPassphraseStrategy = MissingKeyPassphraseStrategy.INTERACTIVE;
|
private MissingKeyPassphraseStrategy missingKeyPassphraseStrategy = MissingKeyPassphraseStrategy.INTERACTIVE;
|
||||||
|
|
||||||
|
private MultiPassStrategy multiPassStrategy = new InMemoryMultiPassStrategy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consider signatures on the message made before the given timestamp invalid.
|
* Consider signatures on the message made before the given timestamp invalid.
|
||||||
|
@ -327,4 +330,26 @@ public class ConsumerOptions {
|
||||||
MissingKeyPassphraseStrategy getMissingKeyPassphraseStrategy() {
|
MissingKeyPassphraseStrategy getMissingKeyPassphraseStrategy() {
|
||||||
return missingKeyPassphraseStrategy;
|
return missingKeyPassphraseStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a custom multi-pass strategy for processing cleartext-signed messages.
|
||||||
|
* Uses {@link InMemoryMultiPassStrategy} by default.
|
||||||
|
*
|
||||||
|
* @param multiPassStrategy multi-pass caching strategy
|
||||||
|
* @return builder
|
||||||
|
*/
|
||||||
|
public ConsumerOptions setMultiPassStrategy(@Nonnull MultiPassStrategy multiPassStrategy) {
|
||||||
|
this.multiPassStrategy = multiPassStrategy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the currently configured {@link MultiPassStrategy}.
|
||||||
|
* Defaults to {@link InMemoryMultiPassStrategy}.
|
||||||
|
*
|
||||||
|
* @return multi-pass strategy
|
||||||
|
*/
|
||||||
|
public MultiPassStrategy getMultiPassStrategy() {
|
||||||
|
return multiPassStrategy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,31 +4,48 @@
|
||||||
|
|
||||||
package org.pgpainless.decryption_verification;
|
package org.pgpainless.decryption_verification;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.pgpainless.decryption_verification.cleartext_signatures.VerifyCleartextSignaturesImpl;
|
||||||
|
import org.pgpainless.exception.WrongConsumingMethodException;
|
||||||
|
|
||||||
public class DecryptionBuilder implements DecryptionBuilderInterface {
|
public class DecryptionBuilder implements DecryptionBuilderInterface {
|
||||||
|
|
||||||
private InputStream inputStream;
|
public static int BUFFER_SIZE = 4096;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DecryptWith onInputStream(@Nonnull InputStream inputStream) {
|
public DecryptWith onInputStream(@Nonnull InputStream inputStream) {
|
||||||
this.inputStream = inputStream;
|
return new DecryptWithImpl(inputStream);
|
||||||
return new DecryptWithImpl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DecryptWithImpl implements DecryptWith {
|
class DecryptWithImpl implements DecryptWith {
|
||||||
|
|
||||||
|
private BufferedInputStream inputStream;
|
||||||
|
|
||||||
|
DecryptWithImpl(InputStream inputStream) {
|
||||||
|
this.inputStream = new BufferedInputStream(inputStream, BUFFER_SIZE);
|
||||||
|
this.inputStream.mark(BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DecryptionStream withOptions(ConsumerOptions consumerOptions) throws PGPException, IOException {
|
public DecryptionStream withOptions(ConsumerOptions consumerOptions) throws PGPException, IOException {
|
||||||
if (consumerOptions == null) {
|
if (consumerOptions == null) {
|
||||||
throw new IllegalArgumentException("Consumer options cannot be null.");
|
throw new IllegalArgumentException("Consumer options cannot be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return DecryptionStreamFactory.create(inputStream, consumerOptions);
|
try {
|
||||||
|
return DecryptionStreamFactory.create(inputStream, consumerOptions);
|
||||||
|
} catch (WrongConsumingMethodException e) {
|
||||||
|
inputStream.reset();
|
||||||
|
return new VerifyCleartextSignaturesImpl()
|
||||||
|
.onInputStream(inputStream)
|
||||||
|
.withOptions(consumerOptions)
|
||||||
|
.getVerificationStream();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,8 @@ public final class DecryptionStreamFactory {
|
||||||
|
|
||||||
private DecryptionStream parseOpenPGPDataAndCreateDecryptionStream(InputStream inputStream) throws IOException, PGPException {
|
private DecryptionStream parseOpenPGPDataAndCreateDecryptionStream(InputStream inputStream) throws IOException, PGPException {
|
||||||
// Make sure we handle armored and non-armored data properly
|
// Make sure we handle armored and non-armored data properly
|
||||||
BufferedInputStream bufferedIn = new BufferedInputStream(inputStream);
|
BufferedInputStream bufferedIn = new BufferedInputStream(inputStream, 512);
|
||||||
|
bufferedIn.mark(512);
|
||||||
InputStream decoderStream;
|
InputStream decoderStream;
|
||||||
PGPObjectFactory objectFactory;
|
PGPObjectFactory objectFactory;
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,9 @@ public class CleartextSignatureProcessor {
|
||||||
|
|
||||||
private final ArmoredInputStream in;
|
private final ArmoredInputStream in;
|
||||||
private final ConsumerOptions options;
|
private final ConsumerOptions options;
|
||||||
private final MultiPassStrategy multiPassStrategy;
|
|
||||||
|
|
||||||
public CleartextSignatureProcessor(InputStream inputStream,
|
public CleartextSignatureProcessor(InputStream inputStream,
|
||||||
ConsumerOptions options,
|
ConsumerOptions options)
|
||||||
MultiPassStrategy multiPassStrategy)
|
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (inputStream instanceof ArmoredInputStream) {
|
if (inputStream instanceof ArmoredInputStream) {
|
||||||
this.in = (ArmoredInputStream) inputStream;
|
this.in = (ArmoredInputStream) inputStream;
|
||||||
|
@ -43,7 +41,6 @@ public class CleartextSignatureProcessor {
|
||||||
this.in = ArmoredInputStreamFactory.get(inputStream);
|
this.in = ArmoredInputStreamFactory.get(inputStream);
|
||||||
}
|
}
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.multiPassStrategy = multiPassStrategy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,6 +64,7 @@ public class CleartextSignatureProcessor {
|
||||||
.setSymmetricKeyAlgorithm(SymmetricKeyAlgorithm.NULL)
|
.setSymmetricKeyAlgorithm(SymmetricKeyAlgorithm.NULL)
|
||||||
.setFileEncoding(StreamEncoding.TEXT);
|
.setFileEncoding(StreamEncoding.TEXT);
|
||||||
|
|
||||||
|
MultiPassStrategy multiPassStrategy = options.getMultiPassStrategy();
|
||||||
PGPSignatureList signatures = ClearsignedMessageUtil.detachSignaturesFromInbandClearsignedMessage(in, multiPassStrategy.getMessageOutputStream());
|
PGPSignatureList signatures = ClearsignedMessageUtil.detachSignaturesFromInbandClearsignedMessage(in, multiPassStrategy.getMessageOutputStream());
|
||||||
|
|
||||||
for (PGPSignature signature : signatures) {
|
for (PGPSignature signature : signatures) {
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
package org.pgpainless.decryption_verification.cleartext_signatures;
|
package org.pgpainless.decryption_verification.cleartext_signatures;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
@ -20,23 +19,7 @@ public interface VerifyCleartextSignatures {
|
||||||
* @param inputStream inputstream
|
* @param inputStream inputstream
|
||||||
* @return api handle
|
* @return api handle
|
||||||
*/
|
*/
|
||||||
WithStrategy onInputStream(InputStream inputStream);
|
VerifyWith onInputStream(InputStream inputStream);
|
||||||
|
|
||||||
interface WithStrategy {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide a {@link MultiPassStrategy} which is used to store the message content.
|
|
||||||
* Since cleartext-signed messages cannot be processed in one pass, the message has to be passed twice.
|
|
||||||
* Therefore the user needs to decide upon a strategy where to cache/store the message between the passes.
|
|
||||||
* This could be {@link MultiPassStrategy#writeMessageToFile(File)} or {@link MultiPassStrategy#keepMessageInMemory()},
|
|
||||||
* depending on message size and use-case.
|
|
||||||
*
|
|
||||||
* @param multiPassStrategy strategy
|
|
||||||
* @return api handle
|
|
||||||
*/
|
|
||||||
VerifyWith withStrategy(MultiPassStrategy multiPassStrategy);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
interface VerifyWith {
|
interface VerifyWith {
|
||||||
|
|
||||||
|
|
|
@ -12,31 +12,18 @@ import org.pgpainless.decryption_verification.ConsumerOptions;
|
||||||
public class VerifyCleartextSignaturesImpl implements VerifyCleartextSignatures {
|
public class VerifyCleartextSignaturesImpl implements VerifyCleartextSignatures {
|
||||||
|
|
||||||
private InputStream inputStream;
|
private InputStream inputStream;
|
||||||
private MultiPassStrategy multiPassStrategy;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WithStrategy onInputStream(InputStream inputStream) {
|
public VerifyWithImpl onInputStream(InputStream inputStream) {
|
||||||
VerifyCleartextSignaturesImpl.this.inputStream = inputStream;
|
VerifyCleartextSignaturesImpl.this.inputStream = inputStream;
|
||||||
return new WithStrategyImpl();
|
return new VerifyWithImpl();
|
||||||
}
|
|
||||||
|
|
||||||
public class WithStrategyImpl implements WithStrategy {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VerifyWith withStrategy(MultiPassStrategy multiPassStrategy) {
|
|
||||||
if (multiPassStrategy == null) {
|
|
||||||
throw new NullPointerException("MultiPassStrategy cannot be null.");
|
|
||||||
}
|
|
||||||
VerifyCleartextSignaturesImpl.this.multiPassStrategy = multiPassStrategy;
|
|
||||||
return new VerifyWithImpl();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VerifyWithImpl implements VerifyWith {
|
public class VerifyWithImpl implements VerifyWith {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CleartextSignatureProcessor withOptions(ConsumerOptions options) throws IOException {
|
public CleartextSignatureProcessor withOptions(ConsumerOptions options) throws IOException {
|
||||||
return new CleartextSignatureProcessor(inputStream, options, multiPassStrategy);
|
return new CleartextSignatureProcessor(inputStream, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,9 @@ import org.bouncycastle.util.io.Streams;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.algorithm.DocumentSignatureType;
|
import org.pgpainless.algorithm.DocumentSignatureType;
|
||||||
import org.pgpainless.decryption_verification.cleartext_signatures.CleartextSignatureProcessor;
|
|
||||||
import org.pgpainless.decryption_verification.cleartext_signatures.InMemoryMultiPassStrategy;
|
import org.pgpainless.decryption_verification.cleartext_signatures.InMemoryMultiPassStrategy;
|
||||||
import org.pgpainless.decryption_verification.cleartext_signatures.MultiPassStrategy;
|
import org.pgpainless.decryption_verification.cleartext_signatures.MultiPassStrategy;
|
||||||
|
import org.pgpainless.decryption_verification.cleartext_signatures.VerifyCleartextSignaturesImpl;
|
||||||
import org.pgpainless.encryption_signing.EncryptionStream;
|
import org.pgpainless.encryption_signing.EncryptionStream;
|
||||||
import org.pgpainless.encryption_signing.ProducerOptions;
|
import org.pgpainless.encryption_signing.ProducerOptions;
|
||||||
import org.pgpainless.encryption_signing.SigningOptions;
|
import org.pgpainless.encryption_signing.SigningOptions;
|
||||||
|
@ -79,12 +79,11 @@ public class CleartextSignatureVerificationTest {
|
||||||
.addVerificationCert(signingKeys);
|
.addVerificationCert(signingKeys);
|
||||||
|
|
||||||
InMemoryMultiPassStrategy multiPassStrategy = MultiPassStrategy.keepMessageInMemory();
|
InMemoryMultiPassStrategy multiPassStrategy = MultiPassStrategy.keepMessageInMemory();
|
||||||
CleartextSignatureProcessor processor = PGPainless.verifyCleartextSignedMessage()
|
options.setMultiPassStrategy(multiPassStrategy);
|
||||||
|
DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify()
|
||||||
.onInputStream(new ByteArrayInputStream(MESSAGE_SIGNED))
|
.onInputStream(new ByteArrayInputStream(MESSAGE_SIGNED))
|
||||||
.withStrategy(multiPassStrategy)
|
|
||||||
.withOptions(options);
|
.withOptions(options);
|
||||||
|
|
||||||
DecryptionStream decryptionStream = processor.getVerificationStream();
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
Streams.pipeAll(decryptionStream, out);
|
Streams.pipeAll(decryptionStream, out);
|
||||||
decryptionStream.close();
|
decryptionStream.close();
|
||||||
|
@ -107,13 +106,11 @@ public class CleartextSignatureVerificationTest {
|
||||||
File tempDir = TestUtils.createTempDirectory();
|
File tempDir = TestUtils.createTempDirectory();
|
||||||
File file = new File(tempDir, "file");
|
File file = new File(tempDir, "file");
|
||||||
MultiPassStrategy multiPassStrategy = MultiPassStrategy.writeMessageToFile(file);
|
MultiPassStrategy multiPassStrategy = MultiPassStrategy.writeMessageToFile(file);
|
||||||
CleartextSignatureProcessor processor = PGPainless.verifyCleartextSignedMessage()
|
options.setMultiPassStrategy(multiPassStrategy);
|
||||||
|
DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify()
|
||||||
.onInputStream(new ByteArrayInputStream(MESSAGE_SIGNED))
|
.onInputStream(new ByteArrayInputStream(MESSAGE_SIGNED))
|
||||||
.withStrategy(multiPassStrategy)
|
|
||||||
.withOptions(options);
|
.withOptions(options);
|
||||||
|
|
||||||
DecryptionStream decryptionStream = processor.getVerificationStream();
|
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
Streams.pipeAll(decryptionStream, out);
|
Streams.pipeAll(decryptionStream, out);
|
||||||
decryptionStream.close();
|
decryptionStream.close();
|
||||||
|
@ -173,18 +170,6 @@ public class CleartextSignatureVerificationTest {
|
||||||
assertEquals(1, metadata.getVerifiedSignatures().size());
|
assertEquals(1, metadata.getVerifiedSignatures().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void consumingCleartextSignedMessageWithNormalAPIThrowsWrongConsumingMethodException() throws IOException, PGPException {
|
|
||||||
PGPPublicKeyRing certificate = TestKeys.getEmilPublicKeyRing();
|
|
||||||
ConsumerOptions options = new ConsumerOptions()
|
|
||||||
.addVerificationCert(certificate);
|
|
||||||
|
|
||||||
assertThrows(WrongConsumingMethodException.class, () ->
|
|
||||||
PGPainless.decryptAndOrVerify()
|
|
||||||
.onInputStream(new ByteArrayInputStream(MESSAGE_SIGNED))
|
|
||||||
.withOptions(options));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void consumingInlineSignedMessageWithCleartextSignedVerificationApiThrowsWrongConsumingMethodException() throws PGPException, IOException {
|
public void consumingInlineSignedMessageWithCleartextSignedVerificationApiThrowsWrongConsumingMethodException() throws PGPException, IOException {
|
||||||
String inlineSignedMessage = "-----BEGIN PGP MESSAGE-----\n" +
|
String inlineSignedMessage = "-----BEGIN PGP MESSAGE-----\n" +
|
||||||
|
@ -207,11 +192,10 @@ public class CleartextSignatureVerificationTest {
|
||||||
.addVerificationCert(certificate);
|
.addVerificationCert(certificate);
|
||||||
|
|
||||||
assertThrows(WrongConsumingMethodException.class, () ->
|
assertThrows(WrongConsumingMethodException.class, () ->
|
||||||
PGPainless.verifyCleartextSignedMessage()
|
new VerifyCleartextSignaturesImpl()
|
||||||
.onInputStream(new ByteArrayInputStream(inlineSignedMessage.getBytes(StandardCharsets.UTF_8)))
|
.onInputStream(new ByteArrayInputStream(inlineSignedMessage.getBytes(StandardCharsets.UTF_8)))
|
||||||
.withStrategy(new InMemoryMultiPassStrategy())
|
.withOptions(options)
|
||||||
.withOptions(options)
|
.getVerificationStream());
|
||||||
.getVerificationStream());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -223,7 +207,7 @@ public class CleartextSignatureVerificationTest {
|
||||||
ByteArrayOutputStream signedOut = new ByteArrayOutputStream();
|
ByteArrayOutputStream signedOut = new ByteArrayOutputStream();
|
||||||
EncryptionStream signingStream = PGPainless.encryptAndOrSign().onOutputStream(signedOut)
|
EncryptionStream signingStream = PGPainless.encryptAndOrSign().onOutputStream(signedOut)
|
||||||
.withOptions(ProducerOptions.sign(SigningOptions.get()
|
.withOptions(ProducerOptions.sign(SigningOptions.get()
|
||||||
.addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKey, DocumentSignatureType.CANONICAL_TEXT_DOCUMENT))
|
.addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKey, DocumentSignatureType.CANONICAL_TEXT_DOCUMENT))
|
||||||
.setCleartextSigned());
|
.setCleartextSigned());
|
||||||
|
|
||||||
Streams.pipeAll(msgIn, signingStream);
|
Streams.pipeAll(msgIn, signingStream);
|
||||||
|
@ -232,12 +216,10 @@ public class CleartextSignatureVerificationTest {
|
||||||
String signed = signedOut.toString();
|
String signed = signedOut.toString();
|
||||||
|
|
||||||
ByteArrayInputStream signedIn = new ByteArrayInputStream(signed.getBytes(StandardCharsets.UTF_8));
|
ByteArrayInputStream signedIn = new ByteArrayInputStream(signed.getBytes(StandardCharsets.UTF_8));
|
||||||
DecryptionStream verificationStream = PGPainless.verifyCleartextSignedMessage()
|
DecryptionStream verificationStream = PGPainless.decryptAndOrVerify()
|
||||||
.onInputStream(signedIn)
|
.onInputStream(signedIn)
|
||||||
.withStrategy(new InMemoryMultiPassStrategy())
|
|
||||||
.withOptions(new ConsumerOptions()
|
.withOptions(new ConsumerOptions()
|
||||||
.addVerificationCert(TestKeys.getEmilPublicKeyRing()))
|
.addVerificationCert(TestKeys.getEmilPublicKeyRing()));
|
||||||
.getVerificationStream();
|
|
||||||
|
|
||||||
ByteArrayOutputStream msgOut = new ByteArrayOutputStream();
|
ByteArrayOutputStream msgOut = new ByteArrayOutputStream();
|
||||||
Streams.pipeAll(verificationStream, msgOut);
|
Streams.pipeAll(verificationStream, msgOut);
|
||||||
|
|
|
@ -7,7 +7,6 @@ package org.pgpainless.example;
|
||||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -24,11 +23,9 @@ import org.pgpainless.algorithm.DocumentSignatureType;
|
||||||
import org.pgpainless.decryption_verification.ConsumerOptions;
|
import org.pgpainless.decryption_verification.ConsumerOptions;
|
||||||
import org.pgpainless.decryption_verification.DecryptionStream;
|
import org.pgpainless.decryption_verification.DecryptionStream;
|
||||||
import org.pgpainless.decryption_verification.OpenPgpMetadata;
|
import org.pgpainless.decryption_verification.OpenPgpMetadata;
|
||||||
import org.pgpainless.decryption_verification.cleartext_signatures.InMemoryMultiPassStrategy;
|
|
||||||
import org.pgpainless.encryption_signing.EncryptionStream;
|
import org.pgpainless.encryption_signing.EncryptionStream;
|
||||||
import org.pgpainless.encryption_signing.ProducerOptions;
|
import org.pgpainless.encryption_signing.ProducerOptions;
|
||||||
import org.pgpainless.encryption_signing.SigningOptions;
|
import org.pgpainless.encryption_signing.SigningOptions;
|
||||||
import org.pgpainless.exception.WrongConsumingMethodException;
|
|
||||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
|
||||||
public class DecryptOrVerify {
|
public class DecryptOrVerify {
|
||||||
|
@ -97,22 +94,10 @@ public class DecryptOrVerify {
|
||||||
for (String signed : new String[] {INBAND_SIGNED, CLEARTEXT_SIGNED}) {
|
for (String signed : new String[] {INBAND_SIGNED, CLEARTEXT_SIGNED}) {
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(signed.getBytes(StandardCharsets.UTF_8));
|
ByteArrayInputStream in = new ByteArrayInputStream(signed.getBytes(StandardCharsets.UTF_8));
|
||||||
BufferedInputStream bufIn = new BufferedInputStream(in);
|
|
||||||
bufIn.mark(512);
|
|
||||||
DecryptionStream verificationStream;
|
DecryptionStream verificationStream;
|
||||||
try {
|
|
||||||
verificationStream = PGPainless.decryptAndOrVerify()
|
verificationStream = PGPainless.decryptAndOrVerify()
|
||||||
.onInputStream(bufIn)
|
.onInputStream(in)
|
||||||
.withOptions(options);
|
.withOptions(options);
|
||||||
} catch (WrongConsumingMethodException e) {
|
|
||||||
bufIn.reset();
|
|
||||||
// Cleartext Signed Message
|
|
||||||
verificationStream = PGPainless.verifyCleartextSignedMessage()
|
|
||||||
.onInputStream(bufIn)
|
|
||||||
.withStrategy(new InMemoryMultiPassStrategy())
|
|
||||||
.withOptions(options)
|
|
||||||
.getVerificationStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
Streams.pipeAll(verificationStream, out);
|
Streams.pipeAll(verificationStream, out);
|
||||||
verificationStream.close();
|
verificationStream.close();
|
||||||
|
@ -140,11 +125,9 @@ public class DecryptOrVerify {
|
||||||
|
|
||||||
ByteArrayInputStream signedIn = new ByteArrayInputStream(out.toByteArray());
|
ByteArrayInputStream signedIn = new ByteArrayInputStream(out.toByteArray());
|
||||||
|
|
||||||
DecryptionStream verificationStream = PGPainless.verifyCleartextSignedMessage()
|
DecryptionStream verificationStream = PGPainless.decryptAndOrVerify()
|
||||||
.onInputStream(signedIn)
|
.onInputStream(signedIn)
|
||||||
.withStrategy(new InMemoryMultiPassStrategy())
|
.withOptions(new ConsumerOptions().addVerificationCert(certificate));
|
||||||
.withOptions(new ConsumerOptions().addVerificationCert(certificate))
|
|
||||||
.getVerificationStream();
|
|
||||||
|
|
||||||
ByteArrayOutputStream plain = new ByteArrayOutputStream();
|
ByteArrayOutputStream plain = new ByteArrayOutputStream();
|
||||||
Streams.pipeAll(verificationStream, plain);
|
Streams.pipeAll(verificationStream, plain);
|
||||||
|
|
Loading…
Reference in a new issue