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

Cleartext signature framework: Reuse ConsumerOptions

This commit is contained in:
Paul Schaub 2021-08-28 11:39:50 +02:00
parent 943360aa65
commit 2885ff7a14
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
4 changed files with 43 additions and 15 deletions

View file

@ -15,6 +15,8 @@
*/ */
package org.pgpainless.signature.cleartext_signatures; package org.pgpainless.signature.cleartext_signatures;
import static org.pgpainless.signature.SignatureValidator.signatureWasCreatedInBounds;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -28,10 +30,10 @@ import org.bouncycastle.bcpg.ArmoredInputStream;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureList;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.decryption_verification.ConsumerOptions;
import org.pgpainless.exception.SignatureValidationException; import org.pgpainless.exception.SignatureValidationException;
import org.pgpainless.signature.CertificateValidator; import org.pgpainless.signature.CertificateValidator;
import org.pgpainless.signature.SignatureVerifier; import org.pgpainless.signature.SignatureVerifier;
@ -45,11 +47,11 @@ public class CleartextSignatureProcessor {
private static final Logger LOGGER = Logger.getLogger(CleartextSignatureProcessor.class.getName()); private static final Logger LOGGER = Logger.getLogger(CleartextSignatureProcessor.class.getName());
private final ArmoredInputStream in; private final ArmoredInputStream in;
private final PGPPublicKeyRingCollection verificationKeys; private final ConsumerOptions options;
private final MultiPassStrategy multiPassStrategy; private final MultiPassStrategy multiPassStrategy;
public CleartextSignatureProcessor(InputStream inputStream, public CleartextSignatureProcessor(InputStream inputStream,
PGPPublicKeyRingCollection verificationKeys, ConsumerOptions options,
MultiPassStrategy multiPassStrategy) MultiPassStrategy multiPassStrategy)
throws IOException { throws IOException {
if (inputStream instanceof ArmoredInputStream) { if (inputStream instanceof ArmoredInputStream) {
@ -57,7 +59,7 @@ public class CleartextSignatureProcessor {
} else { } else {
this.in = ArmoredInputStreamFactory.get(inputStream); this.in = ArmoredInputStreamFactory.get(inputStream);
} }
this.verificationKeys = verificationKeys; this.options = options;
this.multiPassStrategy = multiPassStrategy; this.multiPassStrategy = multiPassStrategy;
} }
@ -81,7 +83,7 @@ public class CleartextSignatureProcessor {
for (PGPSignature signature : signatures) { for (PGPSignature signature : signatures) {
PGPPublicKeyRing certificate = null; PGPPublicKeyRing certificate = null;
PGPPublicKey signingKey = null; PGPPublicKey signingKey = null;
for (PGPPublicKeyRing cert : verificationKeys) { for (PGPPublicKeyRing cert : options.getCertificates()) {
signingKey = cert.getPublicKey(signature.getKeyID()); signingKey = cert.getPublicKey(signature.getKeyID());
if (signingKey != null) { if (signingKey != null) {
certificate = cert; certificate = cert;
@ -94,6 +96,7 @@ public class CleartextSignatureProcessor {
} }
try { try {
signatureWasCreatedInBounds(options.getVerifyNotBefore(), options.getVerifyNotAfter()).verify(signature);
SignatureVerifier.initializeSignatureAndUpdateWithSignedData(signature, multiPassStrategy.getMessageInputStream(), signingKey); SignatureVerifier.initializeSignatureAndUpdateWithSignedData(signature, multiPassStrategy.getMessageInputStream(), signingKey);
CertificateValidator.validateCertificateAndVerifyInitializedSignature(signature, certificate, PGPainless.getPolicy()); CertificateValidator.validateCertificateAndVerifyInitializedSignature(signature, certificate, PGPainless.getPolicy());
return signature; return signature;

View file

@ -22,6 +22,7 @@ import java.io.InputStream;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.pgpainless.decryption_verification.ConsumerOptions;
/** /**
* Interface defining the API for verification of cleartext signed documents. * Interface defining the API for verification of cleartext signed documents.
@ -53,6 +54,15 @@ public interface VerifyCleartextSignatures {
interface VerifyWith { interface VerifyWith {
/**
* Pass in consumer options like verification certificates, acceptable date ranges etc.
*
* @param options options
* @return processor
* @throws IOException in case of an IO error
*/
CleartextSignatureProcessor withOptions(ConsumerOptions options) throws IOException;
/** /**
* Pass in the verification key ring. * Pass in the verification key ring.
* *
@ -60,7 +70,10 @@ public interface VerifyCleartextSignatures {
* @return processor * @return processor
* @throws PGPException if the keys cannot be converted to a {@link PGPPublicKeyRingCollection}. * @throws PGPException if the keys cannot be converted to a {@link PGPPublicKeyRingCollection}.
* @throws IOException if the keys cannot be parsed properly * @throws IOException if the keys cannot be parsed properly
*
* @deprecated use {@link #withOptions(ConsumerOptions)} instead.
*/ */
@Deprecated
CleartextSignatureProcessor verifyWith(PGPPublicKeyRing publicKey) throws PGPException, IOException; CleartextSignatureProcessor verifyWith(PGPPublicKeyRing publicKey) throws PGPException, IOException;
/** /**
@ -69,7 +82,10 @@ public interface VerifyCleartextSignatures {
* @param publicKeys verification keys * @param publicKeys verification keys
* @return processor * @return processor
* @throws IOException if the keys cannot be parsed properly * @throws IOException if the keys cannot be parsed properly
*
* @deprecated use {@link #withOptions(ConsumerOptions)} instead.
*/ */
@Deprecated
CleartextSignatureProcessor verifyWith(PGPPublicKeyRingCollection publicKeys) throws IOException; CleartextSignatureProcessor verifyWith(PGPPublicKeyRingCollection publicKeys) throws IOException;
} }

View file

@ -17,17 +17,15 @@ package org.pgpainless.signature.cleartext_signatures;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collections;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
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; private MultiPassStrategy multiPassStrategy;
private PGPPublicKeyRingCollection verificationKeys;
@Override @Override
public WithStrategy onInputStream(InputStream inputStream) { public WithStrategy onInputStream(InputStream inputStream) {
@ -50,15 +48,22 @@ public class VerifyCleartextSignaturesImpl implements VerifyCleartextSignatures
public class VerifyWithImpl implements VerifyWith { public class VerifyWithImpl implements VerifyWith {
@Override @Override
public CleartextSignatureProcessor verifyWith(PGPPublicKeyRing publicKey) throws PGPException, IOException { public CleartextSignatureProcessor withOptions(ConsumerOptions options) throws IOException {
VerifyCleartextSignaturesImpl.this.verificationKeys = new PGPPublicKeyRingCollection(Collections.singleton(publicKey)); return new CleartextSignatureProcessor(inputStream, options, multiPassStrategy);
return new CleartextSignatureProcessor(inputStream, verificationKeys, multiPassStrategy); }
@Override
public CleartextSignatureProcessor verifyWith(PGPPublicKeyRing publicKey) throws IOException {
ConsumerOptions options = new ConsumerOptions();
options.addVerificationCert(publicKey);
return new CleartextSignatureProcessor(inputStream, options, multiPassStrategy);
} }
@Override @Override
public CleartextSignatureProcessor verifyWith(PGPPublicKeyRingCollection publicKeys) throws IOException { public CleartextSignatureProcessor verifyWith(PGPPublicKeyRingCollection publicKeys) throws IOException {
VerifyCleartextSignaturesImpl.this.verificationKeys = publicKeys; ConsumerOptions options = new ConsumerOptions();
return new CleartextSignatureProcessor(inputStream, verificationKeys, multiPassStrategy); options.addVerificationCerts(publicKeys);
return new CleartextSignatureProcessor(inputStream, options, multiPassStrategy);
} }
} }
} }

View file

@ -77,12 +77,14 @@ public class CleartextSignatureVerificationTest {
@Test @Test
public void cleartextSignVerification_InMemoryMultiPassStrategy() throws IOException, PGPException { public void cleartextSignVerification_InMemoryMultiPassStrategy() throws IOException, PGPException {
PGPPublicKeyRing signingKeys = TestKeys.getEmilPublicKeyRing(); PGPPublicKeyRing signingKeys = TestKeys.getEmilPublicKeyRing();
ConsumerOptions options = new ConsumerOptions()
.addVerificationCert(signingKeys);
InMemoryMultiPassStrategy multiPassStrategy = MultiPassStrategy.keepMessageInMemory(); InMemoryMultiPassStrategy multiPassStrategy = MultiPassStrategy.keepMessageInMemory();
CleartextSignatureProcessor processor = PGPainless.verifyCleartextSignedMessage() CleartextSignatureProcessor processor = PGPainless.verifyCleartextSignedMessage()
.onInputStream(new ByteArrayInputStream(MESSAGE_SIGNED)) .onInputStream(new ByteArrayInputStream(MESSAGE_SIGNED))
.withStrategy(multiPassStrategy) .withStrategy(multiPassStrategy)
.verifyWith(signingKeys); .withOptions(options);
PGPSignature signature = processor.process(); PGPSignature signature = processor.process();
@ -93,6 +95,8 @@ public class CleartextSignatureVerificationTest {
@Test @Test
public void cleartextSignVerification_FileBasedMultiPassStrategy() throws IOException, PGPException { public void cleartextSignVerification_FileBasedMultiPassStrategy() throws IOException, PGPException {
PGPPublicKeyRing signingKeys = TestKeys.getEmilPublicKeyRing(); PGPPublicKeyRing signingKeys = TestKeys.getEmilPublicKeyRing();
ConsumerOptions options = new ConsumerOptions()
.addVerificationCert(signingKeys);
File tempDir = TestUtils.createTempDirectory(); File tempDir = TestUtils.createTempDirectory();
File file = new File(tempDir, "file"); File file = new File(tempDir, "file");
@ -100,7 +104,7 @@ public class CleartextSignatureVerificationTest {
CleartextSignatureProcessor processor = PGPainless.verifyCleartextSignedMessage() CleartextSignatureProcessor processor = PGPainless.verifyCleartextSignedMessage()
.onInputStream(new ByteArrayInputStream(MESSAGE_SIGNED)) .onInputStream(new ByteArrayInputStream(MESSAGE_SIGNED))
.withStrategy(multiPassStrategy) .withStrategy(multiPassStrategy)
.verifyWith(signingKeys); .withOptions(options);
PGPSignature signature = processor.process(); PGPSignature signature = processor.process();