mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-23 12:52:07 +01:00
Cleartext signature framework: Reuse ConsumerOptions
This commit is contained in:
parent
943360aa65
commit
2885ff7a14
4 changed files with 43 additions and 15 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue