DecryptingInputStream.java 5.61 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.internal.io.stream.InputByteStream
 */
package com.adobe.internal.pdftoolkit.core.cos;

import com.adobe.internal.io.stream.InputByteStream;
import com.adobe.internal.pdftoolkit.core.cos.CosDocument;
import com.adobe.internal.pdftoolkit.core.cos.CosEncryption;
import com.adobe.internal.pdftoolkit.core.cos.CosStream;
import com.adobe.internal.pdftoolkit.core.exceptions.PDFCosParseException;
import com.adobe.internal.pdftoolkit.core.exceptions.PDFIOException;
import com.adobe.internal.pdftoolkit.core.exceptions.PDFSecurityConfigurationException;
import com.adobe.internal.pdftoolkit.core.exceptions.PDFSecurityException;
import com.adobe.internal.pdftoolkit.core.securityframework.EncryptionHandler;
import com.adobe.internal.pdftoolkit.core.securityframework.EncryptionHandlerState;
import com.adobe.internal.pdftoolkit.core.types.ASName;
import com.adobe.internal.pdftoolkit.core.util.ByteOps;
import java.io.IOException;
import java.io.InputStream;

class DecryptingInputStream
extends InputStream {
    private static final int BUF_LEN = 65536;
    private InputStream mReadStream;
    private EncryptionHandlerState mEncryptionHandler;
    private byte[] mEncrypted = new byte[65536];
    private byte[] mSingleByte = new byte[1];
    private byte[] mDecrypted;
    private int mDecryptedPos;
    private boolean mNeedsDecryption;
    private boolean mHasBuffer;
    private boolean mDone;
    private boolean mClosed;

    DecryptingInputStream(CosStream cosStream, InputStream content, EncryptionHandlerState encryptionStateHandler) throws PDFIOException, PDFSecurityException, PDFCosParseException, IOException {
        this.mNeedsDecryption = cosStream.needsDecryption(null);
        this.mEncryptionHandler = encryptionStateHandler;
        this.initialize(cosStream, content);
    }

    DecryptingInputStream(CosStream cosStream, InputStream content) throws PDFIOException, PDFSecurityException, PDFCosParseException, IOException {
        this.mNeedsDecryption = cosStream.needsDecryption(null);
        if (this.mNeedsDecryption) {
            ASName cryptFilter;
            EncryptionHandler streamDecryption = cosStream.getDocument().getEncryption().getStreamDecryptionHandler((cryptFilter = cosStream.getCryptFilter()) == null ? null : cryptFilter.asString(true));
            if (streamDecryption == null) {
                throw new PDFSecurityConfigurationException("Cannot find Security Handler for a stream");
            }
            this.mEncryptionHandler = streamDecryption.createEncryptionHandlerState();
        }
        this.initialize(cosStream, content);
    }

    public int read() throws IOException {
        if (this.read(this.mSingleByte) != 1) {
            return -1;
        }
        return this.mSingleByte[0];
    }

    public int read(byte[] buf) throws IOException {
        return this.read(buf, 0, buf.length);
    }

    public int read(byte[] buf, int off, int len) throws IOException {
        if (this.mClosed) {
            throw new IOException("Cannot read from a closed stream");
        }
        if (!this.mNeedsDecryption) {
            return this.mReadStream.read(buf, off, len);
        }
        if (!this.readBuf()) {
            return -1;
        }
        int retLen = ByteOps.copy(this.mDecrypted, this.mDecryptedPos, buf, off, len);
        this.mDecryptedPos += retLen;
        if (this.mDecryptedPos >= this.mDecrypted.length) {
            this.mHasBuffer = false;
        }
        return retLen;
    }

    private void initialize(CosStream cosStream, InputStream content) throws PDFIOException, IOException, PDFSecurityException, PDFCosParseException {
        this.mReadStream = content;
        int inLen = this.mReadStream.read(this.mEncrypted);
        if (this.mNeedsDecryption) {
            if (this.mEncryptionHandler == null) {
                throw new PDFSecurityConfigurationException("Cannot find Security Handler for a stream");
            }
            this.mDecrypted = this.mEncryptionHandler.init(this.mEncrypted, 0, inLen, cosStream.getDocument().getEncryption().getStreamEncryptionKey(cosStream, false), 2);
            if (this.mDecrypted == null) {
                this.mDecrypted = new byte[0];
            }
        }
        this.mDecryptedPos = 0;
        this.mHasBuffer = true;
        this.mDone = false;
        this.mClosed = false;
    }

    private boolean readBuf() throws IOException {
        if (this.mDone) {
            return false;
        }
        if (!this.mHasBuffer) {
            try {
                int inLen = this.mReadStream.read(this.mEncrypted);
                if (inLen < 0) {
                    this.mDecrypted = this.mEncryptionHandler.finish();
                    this.mDone = true;
                } else {
                    this.mDecrypted = this.mEncryptionHandler.update(this.mEncrypted, 0, inLen);
                }
            }
            catch (PDFSecurityException e) {
                IOException excp = new IOException();
                excp.initCause(e);
                throw excp;
            }
            this.mDecryptedPos = 0;
            this.mHasBuffer = true;
        }
        return true;
    }

    public void close() throws IOException {
        if (this.mReadStream != null) {
            this.mReadStream.close();
        }
        this.mClosed = true;
    }

    public int available() throws IOException {
        if (!this.mDone && !this.mClosed) {
            int approxBytes = this.mDecrypted.length - this.mDecryptedPos - 1;
            if (approxBytes <= 0) {
                return 1;
            }
            return approxBytes;
        }
        return 0;
    }
}