OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [javax/] [crypto/] [CipherInputStream.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* CipherInputStream.java -- Filters input through a cipher.
2
   Copyright (C) 2004  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.crypto;
40
 
41
import java.io.FilterInputStream;
42
import java.io.IOException;
43
import java.io.InputStream;
44
 
45
/**
46
 * This is an {@link java.io.InputStream} that filters its data
47
 * through a {@link Cipher} before returning it. The <code>Cipher</code>
48
 * argument must have been initialized before it is passed to the
49
 * constructor.
50
 *
51
 * @author Casey Marshall (csm@gnu.org)
52
 */
53
public class CipherInputStream extends FilterInputStream
54
{
55
 
56
  // Constants and variables.
57
  // ------------------------------------------------------------------------
58
 
59
  /**
60
   * The underlying {@link Cipher} instance.
61
   */
62
  private Cipher cipher;
63
 
64
  /**
65
   * Data that has been transformed but not read.
66
   */
67
  private byte[] outBuffer;
68
 
69
  /**
70
   * The offset into {@link #outBuffer} where valid data starts.
71
   */
72
  private int outOffset;
73
 
74
  /**
75
   * The number of valid bytes in the {@link #outBuffer}.
76
   */
77
  private int outLength;
78
 
79
  /**
80
   * Byte buffer that is filled with raw data from the underlying input
81
   * stream.
82
   */
83
  private byte[][] inBuffer;
84
 
85
  /**
86
   * The amount of bytes in inBuffer[0] that may be input to the cipher.
87
   */
88
  private int inLength;
89
 
90
  /**
91
   * We set this when the cipher block size is 1, meaning that we can
92
   * transform any amount of data.
93
   */
94
  private boolean isStream;
95
 
96
  private static final int VIRGIN = 0;  // I am born.
97
  private static final int LIVING = 1;  // I am nailed to the hull.
98
  private static final int DYING  = 2;  // I am eaten by sharks.
99
  private static final int DEAD   = 3;
100
  private int state;
101
 
102
  // Constructors.
103
  // ------------------------------------------------------------------------
104
 
105
  /**
106
   * Creates a new input stream with a source input stream and cipher.
107
   *
108
   * @param in     The underlying input stream.
109
   * @param cipher The cipher to filter data through.
110
   */
111
  public CipherInputStream(InputStream in, Cipher cipher)
112
  {
113
    this(in);
114
    this.cipher = cipher;
115
    if (!(isStream = cipher.getBlockSize() == 1))
116
      {
117
        inBuffer = new byte[2][];
118
        inBuffer[0] = new byte[cipher.getBlockSize()];
119
        inBuffer[1] = new byte[cipher.getBlockSize()];
120
        inLength = 0;
121
        outBuffer = new byte[cipher.getBlockSize()];
122
        outOffset = outLength = 0;
123
        state = VIRGIN;
124
      }
125
  }
126
 
127
  /**
128
   * Creates a new input stream without a cipher. This constructor is
129
   * <code>protected</code> because this class does not work without an
130
   * underlying cipher.
131
   *
132
   * @param in The underlying input stream.
133
   */
134
  protected CipherInputStream(InputStream in)
135
  {
136
    super(in);
137
  }
138
 
139
  // Instance methods overriding java.io.FilterInputStream.
140
  // ------------------------------------------------------------------------
141
 
142
  /**
143
   * Returns the number of bytes available without blocking. The value
144
   * returned by this method is never greater than the underlying
145
   * cipher's block size.
146
   *
147
   * @return The number of bytes immediately available.
148
   * @throws java.io.IOException If an I/O exception occurs.
149
   */
150
  public int available() throws IOException
151
  {
152
    if (isStream)
153
      return super.available();
154
    return outLength - outOffset;
155
  }
156
 
157
  /**
158
   * Close this input stream. This method merely calls the {@link
159
   * java.io.InputStream#close()} method of the underlying input stream.
160
   *
161
   * @throws java.io.IOException If an I/O exception occurs.
162
   */
163
  public void close() throws IOException
164
  {
165
    super.close();
166
  }
167
 
168
  /**
169
   * Read a single byte from this input stream; returns -1 on the
170
   * end-of-file.
171
   *
172
   * @return The byte read, or -1 if there are no more bytes.
173
   * @throws java.io.IOExcpetion If an I/O exception occurs.
174
   */
175
  public int read() throws IOException
176
  {
177
    if (isStream)
178
      {
179
        byte[] buf = new byte[1];
180
        int in = super.read();
181
        if (in == -1)
182
          return -1;
183
        buf[0] = (byte) in;
184
        try
185
          {
186
            cipher.update(buf, 0, 1, buf, 0);
187
          }
188
        catch (ShortBufferException shouldNotHappen)
189
          {
190
            throw new IOException(shouldNotHappen.getMessage());
191
          }
192
        return buf[0] & 0xFF;
193
      }
194
    if (state == DEAD) return -1;
195
    if (available() == 0) nextBlock();
196
    if (state == DEAD) return -1;
197
    return outBuffer[outOffset++] & 0xFF;
198
  }
199
 
200
  /**
201
   * Read bytes into an array, returning the number of bytes read or -1
202
   * on the end-of-file.
203
   *
204
   * @param buf The byte array to read into.
205
   * @param off The offset in <code>buf</code> to start.
206
   * @param len The maximum number of bytes to read.
207
   * @return The number of bytes read, or -1 on the end-of-file.
208
   * @throws java.io.IOException If an I/O exception occurs.
209
   */
210
  public int read(byte[] buf, int off, int len) throws IOException
211
  {
212
    if (isStream)
213
      {
214
        len = super.read(buf, off, len);
215
        try
216
          {
217
            cipher.update(buf, off, len, buf, off);
218
          }
219
        catch (ShortBufferException shouldNotHappen)
220
          {
221
            throw new IOException(shouldNotHappen.getMessage());
222
          }
223
        return len;
224
      }
225
 
226
    int count = 0;
227
    while (count < len)
228
      {
229
        if (available() == 0)
230
          nextBlock();
231
        if (state == DEAD)
232
          {
233
            if (count > 0) return count;
234
            else return -1;
235
          }
236
        int l = Math.min(available(), len - count);
237
        System.arraycopy(outBuffer, outOffset, buf, count+off, l);
238
        count += l;
239
        outOffset = outLength = 0;
240
      }
241
    return count;
242
  }
243
 
244
  /**
245
   * Read bytes into an array, returning the number of bytes read or -1
246
   * on the end-of-file.
247
   *
248
   * @param buf The byte arry to read into.
249
   * @return The number of bytes read, or -1 on the end-of-file.
250
   * @throws java.io.IOException If an I/O exception occurs.
251
   */
252
  public int read(byte[] buf) throws IOException
253
  {
254
    return read(buf, 0, buf.length);
255
  }
256
 
257
  /**
258
   * Skip a number of bytes. This class only supports skipping as many
259
   * bytes as are returned by {@link #available()}, which is the number
260
   * of transformed bytes currently in this class's internal buffer.
261
   *
262
   * @param bytes The number of bytes to skip.
263
   * @return The number of bytes skipped.
264
   */
265
  public long skip(long bytes) throws IOException
266
  {
267
    if (isStream)
268
      {
269
        return super.skip(bytes);
270
      }
271
    long ret = 0;
272
    if (bytes > 0 && available() > 0)
273
      {
274
        ret = available();
275
        outOffset = outLength = 0;
276
      }
277
    return ret;
278
  }
279
 
280
  /**
281
   * Returns whether or not this input stream supports the {@link
282
   * #mark(long)} and {@link #reset()} methods; this input stream does
283
   * not, however, and invariably returns <code>false</code>.
284
   *
285
   * @return <code>false</code>
286
   */
287
  public boolean markSupported()
288
  {
289
    return false;
290
  }
291
 
292
  /**
293
   * Set the mark. This method is unsupported and is empty.
294
   *
295
   * @param mark Is ignored.
296
   */
297
  public void mark(int mark)
298
  {
299
  }
300
 
301
  /**
302
   * Reset to the mark. This method is unsupported and is empty.
303
   */
304
  public void reset() throws IOException
305
  {
306
    throw new IOException("reset not supported");
307
  }
308
 
309
  // Own methods.
310
  // -------------------------------------------------------------------------
311
 
312
  private void nextBlock() throws IOException
313
  {
314
    byte[] temp = inBuffer[0];
315
    inBuffer[0] = inBuffer[1];
316
    inBuffer[1] = temp;
317
    int count = 0;
318
    boolean eof = false;
319
 
320
    if (state == VIRGIN || state == LIVING)
321
      {
322
        do
323
          {
324
            int l = in.read(inBuffer[1], count, inBuffer[1].length - count);
325
            if (l == -1)
326
              {
327
                eof = true;
328
                break;
329
              }
330
            count += l;
331
          }
332
        while (count < inBuffer[1].length);
333
      }
334
 
335
    try
336
      {
337
        switch (state)
338
          {
339
          case VIRGIN:
340
            state = LIVING;
341
            nextBlock();
342
            break;
343
          case LIVING:
344
            if (eof)
345
              {
346
                if (count > 0)
347
                  {
348
                    outOffset = cipher.update(inBuffer[0], 0, inLength, outBuffer, 0);
349
                    state = DYING;
350
                  }
351
                else
352
                  {
353
                    outOffset = cipher.doFinal(inBuffer[0], 0, inLength, outBuffer, 0);
354
                    state = DEAD;
355
                  }
356
              }
357
            else
358
              {
359
                outOffset = cipher.update(inBuffer[0], 0, inLength, outBuffer, 0);
360
              }
361
            break;
362
          case DYING:
363
            outOffset = cipher.doFinal(inBuffer[0], 0, inLength, outBuffer, 0);
364
            state = DEAD;
365
            break;
366
          case DEAD:
367
          }
368
      }
369
    catch (ShortBufferException sbe)
370
      {
371
        throw new IOException(sbe.toString());
372
      }
373
    catch (BadPaddingException bpe)
374
      {
375
        throw new IOException(bpe.toString());
376
      }
377
    catch (IllegalBlockSizeException ibse)
378
      {
379
        throw new IOException(ibse.toString());
380
      }
381
    inLength = count;
382
  }
383
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.