001// SPDX-FileCopyrightText: 2018 Paul Schaub <vanitasvitae@fsfe.org> 002// 003// SPDX-License-Identifier: Apache-2.0 004 005package org.pgpainless.decryption_verification; 006 007import java.io.IOException; 008import java.io.InputStream; 009import javax.annotation.Nonnull; 010 011import org.bouncycastle.util.io.Streams; 012 013/** 014 * Decryption Stream that handles updating and verification of detached signatures, 015 * as well as verification of integrity-protected input streams once the stream gets closed. 016 */ 017public class DecryptionStream extends CloseForResultInputStream { 018 019 private final InputStream inputStream; 020 private final IntegrityProtectedInputStream integrityProtectedInputStream; 021 private final InputStream armorStream; 022 023 /** 024 * Create an input stream that handles decryption and - if necessary - integrity protection verification. 025 * 026 * @param wrapped underlying input stream 027 * @param resultBuilder builder for decryption metadata like algorithms, recipients etc. 028 * @param integrityProtectedInputStream in case of data encrypted using SEIP packet close this stream to check integrity 029 * @param armorStream armor stream to verify CRC checksums 030 */ 031 DecryptionStream(@Nonnull InputStream wrapped, 032 @Nonnull OpenPgpMetadata.Builder resultBuilder, 033 IntegrityProtectedInputStream integrityProtectedInputStream, 034 InputStream armorStream) { 035 super(resultBuilder); 036 this.inputStream = wrapped; 037 this.integrityProtectedInputStream = integrityProtectedInputStream; 038 this.armorStream = armorStream; 039 } 040 041 @Override 042 public void close() throws IOException { 043 if (armorStream != null) { 044 Streams.drain(armorStream); 045 } 046 inputStream.close(); 047 if (integrityProtectedInputStream != null) { 048 integrityProtectedInputStream.close(); 049 } 050 super.close(); 051 } 052 053 @Override 054 public int read() throws IOException { 055 int r = inputStream.read(); 056 return r; 057 } 058 059 @Override 060 public int read(@Nonnull byte[] bytes, int offset, int length) throws IOException { 061 int read = inputStream.read(bytes, offset, length); 062 return read; 063 } 064 065}