1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-12-10 06:11:08 +01:00

Improve tests and add signatures to result

This commit is contained in:
Paul Schaub 2020-01-10 15:12:04 +01:00
parent 47300a0694
commit 530a22ba0e
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
8 changed files with 146 additions and 86 deletions

View file

@ -21,6 +21,7 @@ import java.io.InputStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.function.Predicate;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
@ -74,15 +75,17 @@ public class DecryptionBuilder implements DecryptionBuilderInterface {
@Override
public HandleMissingPublicKeys verifyWith(@Nonnull Set<OpenPgpV4Fingerprint> trustedKeyIds,
@Nonnull PGPPublicKeyRingCollection publicKeyRingCollection) {
Set<PGPPublicKeyRing> publicKeyRings = keyRingCollectionToSet(publicKeyRingCollection);
publicKeyRings.removeIf(p -> !trustedKeyIds.contains(new OpenPgpV4Fingerprint(p)));
return verifyWith(publicKeyRings);
}
private Set<PGPPublicKeyRing> keyRingCollectionToSet(PGPPublicKeyRingCollection publicKeyRingCollection) {
Set<PGPPublicKeyRing> publicKeyRings = new HashSet<>();
for (Iterator<PGPPublicKeyRing> i = publicKeyRingCollection.getKeyRings(); i.hasNext(); ) {
PGPPublicKeyRing p = i.next();
OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint(p);
if (trustedKeyIds.contains(fingerprint)) {
publicKeyRings.add(p);
}
publicKeyRings.add(i.next());
}
return verifyWith(publicKeyRings);
return publicKeyRings;
}
@Override

View file

@ -198,8 +198,12 @@ public final class DecryptionStreamFactory {
throw new PGPException("Verification failed - No OnePassSignatures found");
}
while (iterator.hasNext()) {
PGPOnePassSignature signature = iterator.next();
processOnePassSignatures(iterator);
}
private void processOnePassSignatures(Iterator<PGPOnePassSignature> signatures) throws PGPException {
while (signatures.hasNext()) {
PGPOnePassSignature signature = signatures.next();
final long keyId = signature.getKeyID();
resultBuilder.addUnverifiedSignatureKeyId(keyId);

View file

@ -17,10 +17,13 @@ package org.pgpainless.decryption_verification;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSignature;
import org.pgpainless.algorithm.CompressionAlgorithm;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
import org.pgpainless.key.OpenPgpV4Fingerprint;
@ -29,7 +32,9 @@ public class OpenPgpMetadata {
private final Set<Long> recipientKeyIds;
private final OpenPgpV4Fingerprint decryptionFingerprint;
private final Set<Long> unverifiedSignatureKeyIds;
private final Set<PGPSignature> signatures;
private final Set<Long> signatureKeyIds;
private final Map<OpenPgpV4Fingerprint, PGPSignature> verifiedSignatures;
private final Set<OpenPgpV4Fingerprint> verifiedSignaturesFingerprints;
private final SymmetricKeyAlgorithm symmetricKeyAlgorithm;
@ -41,7 +46,9 @@ public class OpenPgpMetadata {
SymmetricKeyAlgorithm symmetricKeyAlgorithm,
CompressionAlgorithm algorithm,
boolean integrityProtected,
Set<Long> unverifiedSignatureKeyIds,
Set<PGPSignature> signatures,
Set<Long> signatureKeyIds,
Map<OpenPgpV4Fingerprint, PGPSignature> verifiedSignatures,
Set<OpenPgpV4Fingerprint> verifiedSignaturesFingerprints) {
this.recipientKeyIds = Collections.unmodifiableSet(recipientKeyIds);
@ -49,7 +56,9 @@ public class OpenPgpMetadata {
this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
this.compressionAlgorithm = algorithm;
this.integrityProtected = integrityProtected;
this.unverifiedSignatureKeyIds = Collections.unmodifiableSet(unverifiedSignatureKeyIds);
this.signatures = Collections.unmodifiableSet(signatures);
this.signatureKeyIds = Collections.unmodifiableSet(signatureKeyIds);
this.verifiedSignatures = Collections.unmodifiableMap(verifiedSignatures);
this.verifiedSignaturesFingerprints = Collections.unmodifiableSet(verifiedSignaturesFingerprints);
}
@ -77,15 +86,23 @@ public class OpenPgpMetadata {
return integrityProtected;
}
public Set<Long> getAllSignatureKeyFingerprints() {
return unverifiedSignatureKeyIds;
public Set<PGPSignature> getSignatures() {
return signatures;
}
public Set<Long> getSignatureKeyIDs() {
return signatureKeyIds;
}
public boolean isSigned() {
return !unverifiedSignatureKeyIds.isEmpty();
return !signatureKeyIds.isEmpty();
}
public Set<OpenPgpV4Fingerprint> getVerifiedSignaturesFingerprints() {
public Map<OpenPgpV4Fingerprint, PGPSignature> getVerifiedSignatures() {
return verifiedSignatures;
}
public Set<OpenPgpV4Fingerprint> getVerifiedSignatureKeyFingerprints() {
return verifiedSignaturesFingerprints;
}
@ -107,16 +124,18 @@ public class OpenPgpMetadata {
return verifiedSignaturesFingerprints.contains(fingerprint);
}
static Builder getBuilder() {
public static Builder getBuilder() {
return new Builder();
}
static class Builder {
public static class Builder {
private final Set<Long> recipientFingerprints = new HashSet<>();
private OpenPgpV4Fingerprint decryptionFingerprint;
private final Set<Long> unverifiedSignatureKeyIds = new HashSet<>();
private final Set<OpenPgpV4Fingerprint> verifiedSignatureFingerprints = new HashSet<>();
private final Set<PGPSignature> signatures = new HashSet<>();
private final Set<Long> signatureKeyIds = new HashSet<>();
private final Map<OpenPgpV4Fingerprint, PGPSignature> verifiedSignatures = new ConcurrentHashMap<>();
private final Set<OpenPgpV4Fingerprint> verifiedSignatureKeyFingerprints = new HashSet<>();
private SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm.NULL;
private CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.UNCOMPRESSED;
private boolean integrityProtected = false;
@ -136,13 +155,23 @@ public class OpenPgpMetadata {
return this;
}
public Builder addSignature(PGPSignature signature) {
signatures.add(signature);
return this;
}
public Builder addUnverifiedSignatureKeyId(Long keyId) {
this.unverifiedSignatureKeyIds.add(keyId);
this.signatureKeyIds.add(keyId);
return this;
}
public Builder putVerifiedSignature(OpenPgpV4Fingerprint fingerprint, PGPSignature verifiedSignature) {
verifiedSignatures.put(fingerprint, verifiedSignature);
return this;
}
public Builder addVerifiedSignatureFingerprint(OpenPgpV4Fingerprint fingerprint) {
this.verifiedSignatureFingerprints.add(fingerprint);
this.verifiedSignatureKeyFingerprints.add(fingerprint);
return this;
}
@ -157,7 +186,10 @@ public class OpenPgpMetadata {
}
public OpenPgpMetadata build() {
return new OpenPgpMetadata(recipientFingerprints, decryptionFingerprint, symmetricKeyAlgorithm, compressionAlgorithm, integrityProtected, unverifiedSignatureKeyIds, verifiedSignatureFingerprints);
return new OpenPgpMetadata(recipientFingerprints, decryptionFingerprint,
symmetricKeyAlgorithm, compressionAlgorithm, integrityProtected,
signatures, signatureKeyIds,
verifiedSignatures, verifiedSignatureKeyFingerprints);
}
}
}

View file

@ -96,6 +96,7 @@ public class SignatureVerifyingInputStream extends FilterInputStream {
}
for (PGPSignature signature : signatureList) {
resultBuilder.addSignature(signature);
OpenPgpV4Fingerprint fingerprint = null;
for (OpenPgpV4Fingerprint f : onePassSignatures.keySet()) {
if (f.getKeyId() == signature.getKeyID()) {
@ -114,6 +115,7 @@ public class SignatureVerifyingInputStream extends FilterInputStream {
throw new SignatureException("Bad Signature of key " + signature.getKeyID());
} else {
LOGGER.log(LEVEL, "Verified signature of key " + Long.toHexString(signature.getKeyID()));
resultBuilder.putVerifiedSignature(fingerprint, signature);
resultBuilder.addVerifiedSignatureFingerprint(fingerprint);
}
}

View file

@ -57,7 +57,7 @@ public final class EncryptionStream extends OutputStream {
private static final int BUFFER_SIZE = 1 << 8;
private final OpenPgpMetadata result;
private final OpenPgpMetadata.Builder resultBuilder = OpenPgpMetadata.getBuilder();
private List<PGPSignatureGenerator> signatureGenerators = new ArrayList<>();
private boolean closed = false;
@ -147,21 +147,11 @@ public final class EncryptionStream extends OutputStream {
PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, new Date(), new byte[BUFFER_SIZE]);
// Prepare result
Set<Long> recipientKeyIds = new HashSet<>();
for (PGPPublicKey recipient : encryptionKeys) {
recipientKeyIds.add(recipient.getKeyID());
resultBuilder.addRecipientKeyId(recipient.getKeyID());
}
Set<Long> signingKeyIds = new HashSet<>();
for (PGPPrivateKey signer : signingKeys) {
signingKeyIds.add(signer.getKeyID());
}
this.result = new OpenPgpMetadata(recipientKeyIds,
null, symmetricKeyAlgorithm,
compressionAlgorithm, true,
signingKeyIds, Collections.emptySet());
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
resultBuilder.setCompressionAlgorithm(compressionAlgorithm);
}
@Override
@ -205,7 +195,10 @@ public final class EncryptionStream extends OutputStream {
// Signing
for (PGPSignatureGenerator signatureGenerator : signatureGenerators) {
try {
signatureGenerator.generate().encode(basicCompressionStream);
PGPSignature signature = signatureGenerator.generate();
signature.encode(basicCompressionStream);
resultBuilder.addSignature(signature);
resultBuilder.addUnverifiedSignatureKeyId(signature.getKeyID());
} catch (PGPException e) {
throw new IOException(e);
}
@ -230,6 +223,9 @@ public final class EncryptionStream extends OutputStream {
}
public OpenPgpMetadata getResult() {
return result;
if (!closed) {
throw new IllegalStateException("EncryptionStream must be closed before accessing the Result.");
}
return resultBuilder.build();
}
}