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

Clean DecryptionStream: We only ever have one IntegrityProtectedInputStream at most

This commit is contained in:
Paul Schaub 2021-09-06 15:14:13 +02:00
parent e5ae09b79c
commit e81ee648d8
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
2 changed files with 23 additions and 16 deletions

View file

@ -19,15 +19,14 @@ import static org.pgpainless.signature.SignatureValidator.signatureWasCreatedInB
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.util.io.Streams;
import org.pgpainless.PGPainless;
import org.pgpainless.signature.DetachedSignature;
import org.pgpainless.signature.CertificateValidator;
import org.pgpainless.exception.SignatureValidationException;
import org.pgpainless.signature.CertificateValidator;
import org.pgpainless.signature.DetachedSignature;
import org.pgpainless.util.IntegrityProtectedInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -44,17 +43,26 @@ public class DecryptionStream extends InputStream {
private final ConsumerOptions options;
private final OpenPgpMetadata.Builder resultBuilder;
private boolean isClosed = false;
private List<IntegrityProtectedInputStream> integrityProtectedInputStreamList;
private final IntegrityProtectedInputStream integrityProtectedInputStream;
private final InputStream armorStream;
/**
* Create an input stream that handles decryption and - if necessary - integrity protection verification.
*
* @param wrapped underlying input stream
* @param options options for consuming, eg. decryption key...
* @param resultBuilder builder for decryption metadata like algorithms, recipients etc.
* @param integrityProtectedInputStream in case of data encrypted using SEIP packet close this stream to check integrity
* @param armorStream armor stream to verify CRC checksums
*/
DecryptionStream(@Nonnull InputStream wrapped, @Nonnull ConsumerOptions options,
@Nonnull OpenPgpMetadata.Builder resultBuilder,
List<IntegrityProtectedInputStream> integrityProtectedInputStreamList,
IntegrityProtectedInputStream integrityProtectedInputStream,
InputStream armorStream) {
this.inputStream = wrapped;
this.options = options;
this.resultBuilder = resultBuilder;
this.integrityProtectedInputStreamList = integrityProtectedInputStreamList;
this.integrityProtectedInputStream = integrityProtectedInputStream;
this.armorStream = armorStream;
}
@ -95,8 +103,8 @@ public class DecryptionStream extends InputStream {
}
inputStream.close();
maybeVerifyDetachedSignatures();
for (IntegrityProtectedInputStream s : integrityProtectedInputStreamList) {
s.close();
if (integrityProtectedInputStream != null) {
integrityProtectedInputStream.close();
}
this.isClosed = true;
}

View file

@ -19,7 +19,6 @@ import java.io.BufferedInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@ -86,7 +85,7 @@ public final class DecryptionStreamFactory {
private static final KeyFingerPrintCalculator keyFingerprintCalculator =
ImplementationFactory.getInstance().getKeyFingerprintCalculator();
private final Map<OpenPgpV4Fingerprint, OnePassSignature> verifiableOnePassSignatures = new HashMap<>();
private final List<IntegrityProtectedInputStream> integrityProtectedStreams = new ArrayList<>();
private IntegrityProtectedInputStream integrityProtectedEncryptedInputStream;
public DecryptionStreamFactory(ConsumerOptions options) {
this.options = options;
@ -158,7 +157,7 @@ public final class DecryptionStreamFactory {
}
}
return new DecryptionStream(inputStream, options, factory.resultBuilder, factory.integrityProtectedStreams,
return new DecryptionStream(inputStream, options, factory.resultBuilder, factory.integrityProtectedEncryptedInputStream,
(decoderStream instanceof ArmoredInputStream) ? decoderStream : null);
}
@ -262,7 +261,9 @@ public final class DecryptionStreamFactory {
throwIfAlgorithmIsRejected(symmetricKeyAlgorithm);
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
return decryptedDataStream;
integrityProtectedEncryptedInputStream = new IntegrityProtectedInputStream(decryptedDataStream, pbeEncryptedData);
return integrityProtectedEncryptedInputStream;
} catch (PGPException e) {
LOGGER.debug("Probable passphrase mismatch, skip PBE encrypted data block", e);
}
@ -341,10 +342,8 @@ public final class DecryptionStreamFactory {
throwIfAlgorithmIsRejected(symmetricKeyAlgorithm);
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
IntegrityProtectedInputStream integrityProtected =
new IntegrityProtectedInputStream(encryptedSessionKey.getDataStream(dataDecryptor), encryptedSessionKey);
integrityProtectedStreams.add(integrityProtected);
return integrityProtected;
integrityProtectedEncryptedInputStream = new IntegrityProtectedInputStream(encryptedSessionKey.getDataStream(dataDecryptor), encryptedSessionKey);
return integrityProtectedEncryptedInputStream;
}
private void throwIfAlgorithmIsRejected(SymmetricKeyAlgorithm algorithm) throws UnacceptableAlgorithmException {