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

Cleartext Signature Framework: Return OpenPgpMetadata

This commit is contained in:
Paul Schaub 2021-09-04 13:41:06 +02:00
parent 90a00e0541
commit 3994f87c78
3 changed files with 37 additions and 15 deletions

View file

@ -20,9 +20,6 @@ import static org.pgpainless.signature.SignatureValidator.signatureWasCreatedInB
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -33,8 +30,13 @@ import org.bouncycastle.openpgp.PGPPublicKeyRing;
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.algorithm.CompressionAlgorithm;
import org.pgpainless.algorithm.StreamEncoding;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
import org.pgpainless.decryption_verification.ConsumerOptions; import org.pgpainless.decryption_verification.ConsumerOptions;
import org.pgpainless.decryption_verification.OpenPgpMetadata;
import org.pgpainless.exception.SignatureValidationException; import org.pgpainless.exception.SignatureValidationException;
import org.pgpainless.key.SubkeyIdentifier;
import org.pgpainless.signature.CertificateValidator; import org.pgpainless.signature.CertificateValidator;
import org.pgpainless.signature.SignatureVerifier; import org.pgpainless.signature.SignatureVerifier;
import org.pgpainless.util.ArmoredInputStreamFactory; import org.pgpainless.util.ArmoredInputStreamFactory;
@ -76,9 +78,13 @@ public class CleartextSignatureProcessor {
* @throws PGPException if the signature cannot be initialized. * @throws PGPException if the signature cannot be initialized.
* @throws SignatureValidationException if the signature is invalid. * @throws SignatureValidationException if the signature is invalid.
*/ */
public PGPSignature process() throws IOException, PGPException { public OpenPgpMetadata process() throws IOException, PGPException {
OpenPgpMetadata.Builder resultBuilder = OpenPgpMetadata.getBuilder();
resultBuilder.setCompressionAlgorithm(CompressionAlgorithm.UNCOMPRESSED)
.setSymmetricKeyAlgorithm(SymmetricKeyAlgorithm.NULL)
.setFileEncoding(StreamEncoding.TEXT);
PGPSignatureList signatures = ClearsignedMessageUtil.detachSignaturesFromInbandClearsignedMessage(in, multiPassStrategy.getMessageOutputStream()); PGPSignatureList signatures = ClearsignedMessageUtil.detachSignaturesFromInbandClearsignedMessage(in, multiPassStrategy.getMessageOutputStream());
Map<PGPSignature, Exception> signatureValidationExceptions = new HashMap<>();
for (PGPSignature signature : signatures) { for (PGPSignature signature : signatures) {
PGPPublicKeyRing certificate = null; PGPPublicKeyRing certificate = null;
@ -90,23 +96,29 @@ public class CleartextSignatureProcessor {
break; break;
} }
} }
if (signingKey == null) {
signatureValidationExceptions.put(signature, new NoSuchElementException("Missing verification key with key-id " + Long.toHexString(signature.getKeyID())));
continue;
}
try { try {
if (signingKey == null) {
throw new SignatureValidationException("Missing verification key with key-id " + Long.toHexString(signature.getKeyID()));
}
SubkeyIdentifier signingKeyIdentifier = new SubkeyIdentifier(certificate, signingKey.getKeyID());
signatureWasCreatedInBounds(options.getVerifyNotBefore(), options.getVerifyNotAfter()).verify(signature); 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; resultBuilder.addVerifiedInbandSignature(new SignatureVerification(signature, signingKeyIdentifier));
} catch (SignatureValidationException e) { } catch (SignatureValidationException e) {
LOGGER.log(Level.INFO, "Cannot verify signature made by key " + Long.toHexString(signature.getKeyID()) + ": " + e.getMessage()); LOGGER.log(Level.INFO, "Cannot verify signature made by key " + Long.toHexString(signature.getKeyID()) + ": " + e.getMessage());
signatureValidationExceptions.put(signature, e); SubkeyIdentifier signingKeyIdentifier = null;
if (signingKey != null) {
signingKeyIdentifier = new SubkeyIdentifier(certificate, signingKey.getKeyID());
}
resultBuilder.addInvalidInbandSignature(new SignatureVerification(signature, signingKeyIdentifier), e);
} }
} }
throw new SignatureValidationException("No valid signatures found.", signatureValidationExceptions); return resultBuilder.build();
} }
} }

View file

@ -15,6 +15,8 @@
*/ */
package org.pgpainless.signature.cleartext_signatures; package org.pgpainless.signature.cleartext_signatures;
import javax.annotation.Nullable;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.pgpainless.exception.SignatureValidationException; import org.pgpainless.exception.SignatureValidationException;
import org.pgpainless.key.SubkeyIdentifier; import org.pgpainless.key.SubkeyIdentifier;
@ -24,7 +26,7 @@ public class SignatureVerification {
private final PGPSignature signature; private final PGPSignature signature;
private final SubkeyIdentifier signingKey; private final SubkeyIdentifier signingKey;
public SignatureVerification(PGPSignature signature, SubkeyIdentifier signingKey) { public SignatureVerification(PGPSignature signature, @Nullable SubkeyIdentifier signingKey) {
this.signature = signature; this.signature = signature;
this.signingKey = signingKey; this.signingKey = signingKey;
} }
@ -33,6 +35,7 @@ public class SignatureVerification {
return signature; return signature;
} }
@Nullable
public SubkeyIdentifier getSigningKey() { public SubkeyIdentifier getSigningKey() {
return signingKey; return signingKey;
} }

View file

@ -18,6 +18,7 @@ package org.pgpainless.decryption_verification;
import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -88,7 +89,10 @@ public class CleartextSignatureVerificationTest {
.withStrategy(multiPassStrategy) .withStrategy(multiPassStrategy)
.withOptions(options); .withOptions(options);
PGPSignature signature = processor.process(); OpenPgpMetadata result = processor.process();
assertTrue(result.isVerified());
PGPSignature signature = result.getVerifiedSignatures().values().iterator().next();
assertEquals(signature.getKeyID(), signingKeys.getPublicKey().getKeyID()); assertEquals(signature.getKeyID(), signingKeys.getPublicKey().getKeyID());
assertArrayEquals(MESSAGE_BODY, multiPassStrategy.getBytes()); assertArrayEquals(MESSAGE_BODY, multiPassStrategy.getBytes());
@ -108,7 +112,10 @@ public class CleartextSignatureVerificationTest {
.withStrategy(multiPassStrategy) .withStrategy(multiPassStrategy)
.withOptions(options); .withOptions(options);
PGPSignature signature = processor.process(); OpenPgpMetadata result = processor.process();
assertTrue(result.isVerified());
PGPSignature signature = result.getVerifiedSignatures().values().iterator().next();
assertEquals(signature.getKeyID(), signingKeys.getPublicKey().getKeyID()); assertEquals(signature.getKeyID(), signingKeys.getPublicKey().getKeyID());
FileInputStream fileIn = new FileInputStream(file); FileInputStream fileIn = new FileInputStream(file);