All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.spongycastle.crypto.io.CipherInputStream Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider for the Bouncy Castle Cryptography APIs for JDK 1.5 to JDK 1.7.

There is a newer version: 1.47.0.3
Show newest version
package org.spongycastle.crypto.io;

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.spongycastle.crypto.BufferedBlockCipher;
import org.spongycastle.crypto.StreamCipher;

/**
 * A CipherInputStream is composed of an InputStream and a BufferedBlockCipher so
 * that read() methods return data that are read in from the
 * underlying InputStream but have been additionally processed by the
 * Cipher.  The Cipher must be fully initialized before being used by
 * a CipherInputStream.
 * 

* For example, if the Cipher is initialized for decryption, the * CipherInputStream will attempt to read in data and decrypt them, * before returning the decrypted data. */ public class CipherInputStream extends FilterInputStream { private BufferedBlockCipher bufferedBlockCipher; private StreamCipher streamCipher; private byte[] buf; private byte[] inBuf; private int bufOff; private int maxBuf; private boolean finalized; private static final int INPUT_BUF_SIZE = 2048; /** * Constructs a CipherInputStream from an InputStream and a * BufferedBlockCipher. */ public CipherInputStream( InputStream is, BufferedBlockCipher cipher) { super(is); this.bufferedBlockCipher = cipher; buf = new byte[cipher.getOutputSize(INPUT_BUF_SIZE)]; inBuf = new byte[INPUT_BUF_SIZE]; } public CipherInputStream( InputStream is, StreamCipher cipher) { super(is); this.streamCipher = cipher; buf = new byte[INPUT_BUF_SIZE]; inBuf = new byte[INPUT_BUF_SIZE]; } /** * grab the next chunk of input from the underlying input stream */ private int nextChunk() throws IOException { int available = super.available(); // must always try to read 1 byte! // some buggy InputStreams return < 0! if (available <= 0) { available = 1; } if (available > inBuf.length) { available = super.read(inBuf, 0, inBuf.length); } else { available = super.read(inBuf, 0, available); } if (available < 0) { if (finalized) { return -1; } try { if (bufferedBlockCipher != null) { maxBuf = bufferedBlockCipher.doFinal(buf, 0); } else { maxBuf = 0; // a stream cipher } } catch (Exception e) { throw new IOException("error processing stream: " + e.toString()); } bufOff = 0; finalized = true; if (bufOff == maxBuf) { return -1; } } else { bufOff = 0; try { if (bufferedBlockCipher != null) { maxBuf = bufferedBlockCipher.processBytes(inBuf, 0, available, buf, 0); } else { streamCipher.processBytes(inBuf, 0, available, buf, 0); maxBuf = available; } } catch (Exception e) { throw new IOException("error processing stream: " + e.toString()); } if (maxBuf == 0) // not enough bytes read for first block... { return nextChunk(); } } return maxBuf; } public int read() throws IOException { if (bufOff == maxBuf) { if (nextChunk() < 0) { return -1; } } return buf[bufOff++] & 0xff; } public int read( byte[] b) throws IOException { return read(b, 0, b.length); } public int read( byte[] b, int off, int len) throws IOException { if (bufOff == maxBuf) { if (nextChunk() < 0) { return -1; } } int available = maxBuf - bufOff; if (len > available) { System.arraycopy(buf, bufOff, b, off, available); bufOff = maxBuf; return available; } else { System.arraycopy(buf, bufOff, b, off, len); bufOff += len; return len; } } public long skip( long n) throws IOException { if (n <= 0) { return 0; } int available = maxBuf - bufOff; if (n > available) { bufOff = maxBuf; return available; } else { bufOff += (int)n; return (int)n; } } public int available() throws IOException { return maxBuf - bufOff; } public void close() throws IOException { super.close(); } public boolean markSupported() { return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy