mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-23 12:52:07 +01:00
Clean DecryptionStream: We only ever have one IntegrityProtectedInputStream at most
This commit is contained in:
parent
e5ae09b79c
commit
e81ee648d8
2 changed files with 23 additions and 16 deletions
|
@ -19,15 +19,14 @@ import static org.pgpainless.signature.SignatureValidator.signatureWasCreatedInB
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.bouncycastle.util.io.Streams;
|
import org.bouncycastle.util.io.Streams;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.signature.DetachedSignature;
|
|
||||||
import org.pgpainless.signature.CertificateValidator;
|
|
||||||
import org.pgpainless.exception.SignatureValidationException;
|
import org.pgpainless.exception.SignatureValidationException;
|
||||||
|
import org.pgpainless.signature.CertificateValidator;
|
||||||
|
import org.pgpainless.signature.DetachedSignature;
|
||||||
import org.pgpainless.util.IntegrityProtectedInputStream;
|
import org.pgpainless.util.IntegrityProtectedInputStream;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -44,17 +43,26 @@ public class DecryptionStream extends InputStream {
|
||||||
private final ConsumerOptions options;
|
private final ConsumerOptions options;
|
||||||
private final OpenPgpMetadata.Builder resultBuilder;
|
private final OpenPgpMetadata.Builder resultBuilder;
|
||||||
private boolean isClosed = false;
|
private boolean isClosed = false;
|
||||||
private List<IntegrityProtectedInputStream> integrityProtectedInputStreamList;
|
private final IntegrityProtectedInputStream integrityProtectedInputStream;
|
||||||
private final InputStream armorStream;
|
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,
|
DecryptionStream(@Nonnull InputStream wrapped, @Nonnull ConsumerOptions options,
|
||||||
@Nonnull OpenPgpMetadata.Builder resultBuilder,
|
@Nonnull OpenPgpMetadata.Builder resultBuilder,
|
||||||
List<IntegrityProtectedInputStream> integrityProtectedInputStreamList,
|
IntegrityProtectedInputStream integrityProtectedInputStream,
|
||||||
InputStream armorStream) {
|
InputStream armorStream) {
|
||||||
this.inputStream = wrapped;
|
this.inputStream = wrapped;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.resultBuilder = resultBuilder;
|
this.resultBuilder = resultBuilder;
|
||||||
this.integrityProtectedInputStreamList = integrityProtectedInputStreamList;
|
this.integrityProtectedInputStream = integrityProtectedInputStream;
|
||||||
this.armorStream = armorStream;
|
this.armorStream = armorStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +103,8 @@ public class DecryptionStream extends InputStream {
|
||||||
}
|
}
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
maybeVerifyDetachedSignatures();
|
maybeVerifyDetachedSignatures();
|
||||||
for (IntegrityProtectedInputStream s : integrityProtectedInputStreamList) {
|
if (integrityProtectedInputStream != null) {
|
||||||
s.close();
|
integrityProtectedInputStream.close();
|
||||||
}
|
}
|
||||||
this.isClosed = true;
|
this.isClosed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import java.io.BufferedInputStream;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -86,7 +85,7 @@ public final class DecryptionStreamFactory {
|
||||||
private static final KeyFingerPrintCalculator keyFingerprintCalculator =
|
private static final KeyFingerPrintCalculator keyFingerprintCalculator =
|
||||||
ImplementationFactory.getInstance().getKeyFingerprintCalculator();
|
ImplementationFactory.getInstance().getKeyFingerprintCalculator();
|
||||||
private final Map<OpenPgpV4Fingerprint, OnePassSignature> verifiableOnePassSignatures = new HashMap<>();
|
private final Map<OpenPgpV4Fingerprint, OnePassSignature> verifiableOnePassSignatures = new HashMap<>();
|
||||||
private final List<IntegrityProtectedInputStream> integrityProtectedStreams = new ArrayList<>();
|
private IntegrityProtectedInputStream integrityProtectedEncryptedInputStream;
|
||||||
|
|
||||||
public DecryptionStreamFactory(ConsumerOptions options) {
|
public DecryptionStreamFactory(ConsumerOptions options) {
|
||||||
this.options = 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);
|
(decoderStream instanceof ArmoredInputStream) ? decoderStream : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +261,9 @@ public final class DecryptionStreamFactory {
|
||||||
throwIfAlgorithmIsRejected(symmetricKeyAlgorithm);
|
throwIfAlgorithmIsRejected(symmetricKeyAlgorithm);
|
||||||
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
|
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
|
||||||
|
|
||||||
return decryptedDataStream;
|
integrityProtectedEncryptedInputStream = new IntegrityProtectedInputStream(decryptedDataStream, pbeEncryptedData);
|
||||||
|
|
||||||
|
return integrityProtectedEncryptedInputStream;
|
||||||
} catch (PGPException e) {
|
} catch (PGPException e) {
|
||||||
LOGGER.debug("Probable passphrase mismatch, skip PBE encrypted data block", e);
|
LOGGER.debug("Probable passphrase mismatch, skip PBE encrypted data block", e);
|
||||||
}
|
}
|
||||||
|
@ -341,10 +342,8 @@ public final class DecryptionStreamFactory {
|
||||||
throwIfAlgorithmIsRejected(symmetricKeyAlgorithm);
|
throwIfAlgorithmIsRejected(symmetricKeyAlgorithm);
|
||||||
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
|
resultBuilder.setSymmetricKeyAlgorithm(symmetricKeyAlgorithm);
|
||||||
|
|
||||||
IntegrityProtectedInputStream integrityProtected =
|
integrityProtectedEncryptedInputStream = new IntegrityProtectedInputStream(encryptedSessionKey.getDataStream(dataDecryptor), encryptedSessionKey);
|
||||||
new IntegrityProtectedInputStream(encryptedSessionKey.getDataStream(dataDecryptor), encryptedSessionKey);
|
return integrityProtectedEncryptedInputStream;
|
||||||
integrityProtectedStreams.add(integrityProtected);
|
|
||||||
return integrityProtected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void throwIfAlgorithmIsRejected(SymmetricKeyAlgorithm algorithm) throws UnacceptableAlgorithmException {
|
private void throwIfAlgorithmIsRejected(SymmetricKeyAlgorithm algorithm) throws UnacceptableAlgorithmException {
|
||||||
|
|
Loading…
Reference in a new issue