History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/crypto/CipherInputStream.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/crypto/CipherInputStream.java+322−0
@@ -0,0 +1,322 @@
1+/*
2+ * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package javax.crypto;
27+
28+import java.io.*;
29+
30+/**
31+ * A CipherInputStream is composed of an InputStream and a Cipher so
32+ * that read() methods return data that are read in from the
33+ * underlying InputStream but have been additionally processed by the
34+ * Cipher. The Cipher must be fully initialized before being used by
35+ * a CipherInputStream.
36+ *
37+ * <p> For example, if the Cipher is initialized for decryption, the
38+ * CipherInputStream will attempt to read in data and decrypt them,
39+ * before returning the decrypted data.
40+ *
41+ * <p> This class adheres strictly to the semantics, especially the
42+ * failure semantics, of its ancestor classes
43+ * java.io.FilterInputStream and java.io.InputStream. This class has
44+ * exactly those methods specified in its ancestor classes, and
45+ * overrides them all. Moreover, this class catches all exceptions
46+ * that are not thrown by its ancestor classes. In particular, the
47+ * <code>skip</code> method skips, and the <code>available</code>
48+ * method counts only data that have been processed by the encapsulated Cipher.
49+ *
50+ * <p> It is crucial for a programmer using this class not to use
51+ * methods that are not defined or overriden in this class (such as a
52+ * new method or constructor that is later added to one of the super
53+ * classes), because the design and implementation of those methods
54+ * are unlikely to have considered security impact with regard to
55+ * CipherInputStream.
56+ *
57+ * @author Li Gong
58+ * @see java.io.InputStream
59+ * @see java.io.FilterInputStream
60+ * @see javax.crypto.Cipher
61+ * @see javax.crypto.CipherOutputStream
62+ *
63+ * @since 1.4
64+ */
65+
66+public class CipherInputStream extends FilterInputStream {
67+
68+ // the cipher engine to use to process stream data
69+ private Cipher cipher;
70+
71+ // the underlying input stream
72+ private InputStream input;
73+
74+ /* the buffer holding data that have been read in from the
75+ underlying stream, but have not been processed by the cipher
76+ engine. the size 512 bytes is somewhat randomly chosen */
77+ private byte[] ibuffer = new byte[512];
78+
79+ // having reached the end of the underlying input stream
80+ private boolean done = false;
81+
82+ /* the buffer holding data that have been processed by the cipher
83+ engine, but have not been read out */
84+ private byte[] obuffer;
85+ // the offset pointing to the next "new" byte
86+ private int ostart = 0;
87+ // the offset pointing to the last "new" byte
88+ private int ofinish = 0;
89+
90+ /**
91+ * private convenience function.
92+ *
93+ * Entry condition: ostart = ofinish
94+ *
95+ * Exit condition: ostart <= ofinish
96+ *
97+ * return (ofinish-ostart) (we have this many bytes for you)
98+ * return 0 (no data now, but could have more later)
99+ * return -1 (absolutely no more data)
100+ */
101+ private int getMoreData() throws IOException {
102+ if (done) return -1;
103+ int readin = input.read(ibuffer);
104+ if (readin == -1) {
105+ done = true;
106+ try {
107+ obuffer = cipher.doFinal();
108+ }
109+ catch (IllegalBlockSizeException e) {obuffer = null;}
110+ catch (BadPaddingException e) {obuffer = null;}
111+ if (obuffer == null)
112+ return -1;
113+ else {
114+ ostart = 0;
115+ ofinish = obuffer.length;
116+ return ofinish;
117+ }
118+ }
119+ try {
120+ obuffer = cipher.update(ibuffer, 0, readin);
121+ } catch (IllegalStateException e) {obuffer = null;};
122+ ostart = 0;
123+ if (obuffer == null)
124+ ofinish = 0;
125+ else ofinish = obuffer.length;
126+ return ofinish;
127+ }
128+
129+ /**
130+ * Constructs a CipherInputStream from an InputStream and a
131+ * Cipher.
132+ * <br>Note: if the specified input stream or cipher is
133+ * null, a NullPointerException may be thrown later when
134+ * they are used.
135+ * @param is the to-be-processed input stream
136+ * @param c an initialized Cipher object
137+ */
138+ public CipherInputStream(InputStream is, Cipher c) {
139+ super(is);
140+ input = is;
141+ cipher = c;
142+ }
143+
144+ /**
145+ * Constructs a CipherInputStream from an InputStream without
146+ * specifying a Cipher. This has the effect of constructing a
147+ * CipherInputStream using a NullCipher.
148+ * <br>Note: if the specified input stream is null, a
149+ * NullPointerException may be thrown later when it is used.
150+ * @param is the to-be-processed input stream
151+ */
152+ protected CipherInputStream(InputStream is) {
153+ super(is);
154+ input = is;
155+ cipher = new NullCipher();
156+ }
157+
158+ /**
159+ * Reads the next byte of data from this input stream. The value
160+ * byte is returned as an <code>int</code> in the range
161+ * <code>0</code> to <code>255</code>. If no byte is available
162+ * because the end of the stream has been reached, the value
163+ * <code>-1</code> is returned. This method blocks until input data
164+ * is available, the end of the stream is detected, or an exception
165+ * is thrown.
166+ * <p>
167+ *
168+ * @return the next byte of data, or <code>-1</code> if the end of the
169+ * stream is reached.
170+ * @exception IOException if an I/O error occurs.
171+ * @since JCE1.2
172+ */
173+ public int read() throws IOException {
174+ if (ostart >= ofinish) {
175+ // we loop for new data as the spec says we are blocking
176+ int i = 0;
177+ while (i == 0) i = getMoreData();
178+ if (i == -1) return -1;
179+ }
180+ return ((int) obuffer[ostart++] & 0xff);
181+ };
182+
183+ /**
184+ * Reads up to <code>b.length</code> bytes of data from this input
185+ * stream into an array of bytes.
186+ * <p>
187+ * The <code>read</code> method of <code>InputStream</code> calls
188+ * the <code>read</code> method of three arguments with the arguments
189+ * <code>b</code>, <code>0</code>, and <code>b.length</code>.
190+ *
191+ * @param b the buffer into which the data is read.
192+ * @return the total number of bytes read into the buffer, or
193+ * <code>-1</code> is there is no more data because the end of
194+ * the stream has been reached.
195+ * @exception IOException if an I/O error occurs.
196+ * @see java.io.InputStream#read(byte[], int, int)
197+ * @since JCE1.2
198+ */
199+ public int read(byte b[]) throws IOException {
200+ return read(b, 0, b.length);
201+ }
202+
203+ /**
204+ * Reads up to <code>len</code> bytes of data from this input stream
205+ * into an array of bytes. This method blocks until some input is
206+ * available. If the first argument is <code>null,</code> up to
207+ * <code>len</code> bytes are read and discarded.
208+ *
209+ * @param b the buffer into which the data is read.
210+ * @param off the start offset in the destination array
211+ * <code>buf</code>
212+ * @param len the maximum number of bytes read.
213+ * @return the total number of bytes read into the buffer, or
214+ * <code>-1</code> if there is no more data because the end of
215+ * the stream has been reached.
216+ * @exception IOException if an I/O error occurs.
217+ * @see java.io.InputStream#read()
218+ * @since JCE1.2
219+ */
220+ public int read(byte b[], int off, int len) throws IOException {
221+ if (ostart >= ofinish) {
222+ // we loop for new data as the spec says we are blocking
223+ int i = 0;
224+ while (i == 0) i = getMoreData();
225+ if (i == -1) return -1;
226+ }
227+ if (len <= 0) {
228+ return 0;
229+ }
230+ int available = ofinish - ostart;
231+ if (len < available) available = len;
232+ if (b != null) {
233+ System.arraycopy(obuffer, ostart, b, off, available);
234+ }
235+ ostart = ostart + available;
236+ return available;
237+ }
238+
239+ /**
240+ * Skips <code>n</code> bytes of input from the bytes that can be read
241+ * from this input stream without blocking.
242+ *
243+ * <p>Fewer bytes than requested might be skipped.
244+ * The actual number of bytes skipped is equal to <code>n</code> or
245+ * the result of a call to
246+ * {@link #available() <code>available</code>},
247+ * whichever is smaller.
248+ * If <code>n</code> is less than zero, no bytes are skipped.
249+ *
250+ * <p>The actual number of bytes skipped is returned.
251+ *
252+ * @param n the number of bytes to be skipped.
253+ * @return the actual number of bytes skipped.
254+ * @exception IOException if an I/O error occurs.
255+ * @since JCE1.2
256+ */
257+ public long skip(long n) throws IOException {
258+ int available = ofinish - ostart;
259+ if (n > available) {
260+ n = available;
261+ }
262+ if (n < 0) {
263+ return 0;
264+ }
265+ ostart += n;
266+ return n;
267+ }
268+
269+ /**
270+ * Returns the number of bytes that can be read from this input
271+ * stream without blocking. The <code>available</code> method of
272+ * <code>InputStream</code> returns <code>0</code>. This method
273+ * <B>should</B> be overridden by subclasses.
274+ *
275+ * @return the number of bytes that can be read from this input stream
276+ * without blocking.
277+ * @exception IOException if an I/O error occurs.
278+ * @since JCE1.2
279+ */
280+ public int available() throws IOException {
281+ return (ofinish - ostart);
282+ }
283+
284+ /**
285+ * Closes this input stream and releases any system resources
286+ * associated with the stream.
287+ * <p>
288+ * The <code>close</code> method of <code>CipherInputStream</code>
289+ * calls the <code>close</code> method of its underlying input
290+ * stream.
291+ *
292+ * @exception IOException if an I/O error occurs.
293+ * @since JCE1.2
294+ */
295+ public void close() throws IOException {
296+ input.close();
297+ try {
298+ // throw away the unprocessed data
299+ cipher.doFinal();
300+ }
301+ catch (BadPaddingException ex) {
302+ }
303+ catch (IllegalBlockSizeException ex) {
304+ }
305+ ostart = 0;
306+ ofinish = 0;
307+ }
308+
309+ /**
310+ * Tests if this input stream supports the <code>mark</code>
311+ * and <code>reset</code> methods, which it does not.
312+ *
313+ * @return <code>false</code>, since this class does not support the
314+ * <code>mark</code> and <code>reset</code> methods.
315+ * @see java.io.InputStream#mark(int)
316+ * @see java.io.InputStream#reset()
317+ * @since JCE1.2
318+ */
319+ public boolean markSupported() {
320+ return false;
321+ }
322+}