001// SPDX-FileCopyrightText: 2021 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.openpgp.PGPEncryptedData;
012import org.bouncycastle.openpgp.PGPException;
013import org.pgpainless.exception.ModificationDetectionException;
014
015public class IntegrityProtectedInputStream extends InputStream {
016
017    private final InputStream inputStream;
018    private final PGPEncryptedData encryptedData;
019    private final ConsumerOptions options;
020
021    public IntegrityProtectedInputStream(InputStream inputStream, PGPEncryptedData encryptedData, ConsumerOptions options) {
022        this.inputStream = inputStream;
023        this.encryptedData = encryptedData;
024        this.options = options;
025    }
026
027    @Override
028    public int read() throws IOException {
029        return inputStream.read();
030    }
031
032    @Override
033    public int read(@Nonnull byte[] b, int offset, int length) throws IOException {
034        return inputStream.read(b, offset, length);
035    }
036
037    @Override
038    public void close() throws IOException {
039        if (encryptedData.isIntegrityProtected() && !options.isIgnoreMDCErrors()) {
040            try {
041                if (!encryptedData.verify()) {
042                    throw new ModificationDetectionException();
043                }
044            } catch (PGPException e) {
045                throw new IOException("Failed to verify integrity protection", e);
046            }
047        }
048    }
049}