KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ch > ethz > ssh2 > crypto > cipher > CipherInputStream


1
2 package ch.ethz.ssh2.crypto.cipher;
3
4 import java.io.IOException JavaDoc;
5 import java.io.InputStream JavaDoc;
6
7 /**
8  * CipherInputStream.
9  *
10  * @author Christian Plattner, plattner@inf.ethz.ch
11  * @version $Id: CipherInputStream.java,v 1.3 2006/02/14 15:17:37 cplattne Exp $
12  */

13 public class CipherInputStream
14 {
15     BlockCipher currentCipher;
16     InputStream JavaDoc bi;
17     byte[] buffer;
18     byte[] enc;
19     int blockSize;
20     int pos;
21
22     /*
23      * We cannot use java.io.BufferedInputStream, since that is not available in
24      * J2ME. Everything could be improved alot here.
25      */

26
27     final int BUFF_SIZE = 2048;
28     byte[] input_buffer = new byte[BUFF_SIZE];
29     int input_buffer_pos = 0;
30     int input_buffer_size = 0;
31
32     public CipherInputStream(BlockCipher tc, InputStream JavaDoc bi)
33     {
34         this.bi = bi;
35         changeCipher(tc);
36     }
37
38     private int fill_buffer() throws IOException JavaDoc
39     {
40         input_buffer_pos = 0;
41         input_buffer_size = bi.read(input_buffer, 0, BUFF_SIZE);
42         return input_buffer_size;
43     }
44
45     private int internal_read(byte[] b, int off, int len) throws IOException JavaDoc
46     {
47         if (input_buffer_size < 0)
48             return -1;
49
50         if (input_buffer_pos >= input_buffer_size)
51         {
52             if (fill_buffer() <= 0)
53                 return -1;
54         }
55         
56         int avail = input_buffer_size - input_buffer_pos;
57         int thiscopy = (len > avail) ? avail : len;
58
59         System.arraycopy(input_buffer, input_buffer_pos, b, off, thiscopy);
60         input_buffer_pos += thiscopy;
61
62         return thiscopy;
63     }
64
65     public void changeCipher(BlockCipher bc)
66     {
67         this.currentCipher = bc;
68         blockSize = bc.getBlockSize();
69         buffer = new byte[blockSize];
70         enc = new byte[blockSize];
71         pos = blockSize;
72     }
73
74     private void getBlock() throws IOException JavaDoc
75     {
76         int n = 0;
77         while (n < blockSize)
78         {
79             int len = internal_read(enc, n, blockSize - n);
80             if (len < 0)
81                 throw new IOException JavaDoc("Cannot read full block, EOF reached.");
82             n += len;
83         }
84
85         try
86         {
87             currentCipher.transformBlock(enc, 0, buffer, 0);
88         }
89         catch (Exception JavaDoc e)
90         {
91             throw new IOException JavaDoc("Error while decrypting block.");
92         }
93         pos = 0;
94     }
95
96     public int read(byte[] dst) throws IOException JavaDoc
97     {
98         return read(dst, 0, dst.length);
99     }
100
101     public int read(byte[] dst, int off, int len) throws IOException JavaDoc
102     {
103         int count = 0;
104
105         while (len > 0)
106         {
107             if (pos >= blockSize)
108                 getBlock();
109
110             int avail = blockSize - pos;
111             int copy = Math.min(avail, len);
112             System.arraycopy(buffer, pos, dst, off, copy);
113             pos += copy;
114             off += copy;
115             len -= copy;
116             count += copy;
117         }
118         return count;
119     }
120
121     public int read() throws IOException JavaDoc
122     {
123         if (pos >= blockSize)
124         {
125             getBlock();
126         }
127         return buffer[pos++] & 0xff;
128     }
129
130     public int readPlain(byte[] b, int off, int len) throws IOException JavaDoc
131     {
132         if (pos != blockSize)
133             throw new IOException JavaDoc("Cannot read plain since crypto buffer is not aligned.");
134         int n = 0;
135         while (n < len)
136         {
137             int cnt = internal_read(b, off + n, len - n);
138             if (cnt < 0)
139                 throw new IOException JavaDoc("Cannot fill buffer, EOF reached.");
140             n += cnt;
141         }
142         return n;
143     }
144 }
145
Popular Tags