comparison src/ch/ethz/ssh2/crypto/cipher/CipherInputStream.java @ 273:91a31873c42a ganymed

start conversion from trilead to ganymed
author Carl Byington <carl@five-ten-sg.com>
date Fri, 18 Jul 2014 11:21:46 -0700
parents
children 071eccdff8ea
comparison
equal deleted inserted replaced
272:ce2f4e397703 273:91a31873c42a
1 /*
2 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
3 * Please refer to the LICENSE.txt for licensing details.
4 */
5 package ch.ethz.ssh2.crypto.cipher;
6
7 import java.io.IOException;
8 import java.io.InputStream;
9
10 /**
11 * CipherInputStream.
12 *
13 * @author Christian Plattner
14 * @version $Id: CipherInputStream.java 11 2011-05-27 14:14:06Z dkocher@sudo.ch $
15 */
16 public class CipherInputStream
17 {
18 BlockCipher currentCipher;
19 InputStream bi;
20 byte[] buffer;
21 byte[] enc;
22 int blockSize;
23 int pos;
24
25 /*
26 * We cannot use java.io.BufferedInputStream, since that is not available in
27 * J2ME. Everything could be improved alot here.
28 */
29
30 private static final int BUFF_SIZE = 8192;
31 byte[] input_buffer = new byte[BUFF_SIZE];
32 int input_buffer_pos = 0;
33 int input_buffer_size = 0;
34
35 public CipherInputStream(BlockCipher tc, InputStream bi)
36 {
37 this.bi = bi;
38 changeCipher(tc);
39 }
40
41 private int fill_buffer() throws IOException
42 {
43 input_buffer_pos = 0;
44 input_buffer_size = 0;
45 input_buffer_size = bi.read(input_buffer, 0, BUFF_SIZE);
46 return input_buffer_size;
47 }
48
49 private int internal_read(byte[] b, int off, int len) throws IOException
50 {
51 if (input_buffer_size < 0)
52 {
53 return -1;
54 }
55
56 if (input_buffer_pos >= input_buffer_size)
57 {
58 if (fill_buffer() <= 0)
59 {
60 return -1;
61 }
62 }
63
64 int avail = input_buffer_size - input_buffer_pos;
65 int thiscopy = (len > avail) ? avail : len;
66
67 System.arraycopy(input_buffer, input_buffer_pos, b, off, thiscopy);
68 input_buffer_pos += thiscopy;
69
70 return thiscopy;
71 }
72
73 public void changeCipher(BlockCipher bc)
74 {
75 this.currentCipher = bc;
76 blockSize = bc.getBlockSize();
77 buffer = new byte[blockSize];
78 enc = new byte[blockSize];
79 pos = blockSize;
80 }
81
82 private void getBlock() throws IOException
83 {
84 int n = 0;
85 while (n < blockSize)
86 {
87 int len = internal_read(enc, n, blockSize - n);
88 if (len < 0)
89 {
90 throw new IOException("Cannot read full block, EOF reached.");
91 }
92 n += len;
93 }
94
95 try
96 {
97 currentCipher.transformBlock(enc, 0, buffer, 0);
98 }
99 catch (Exception e)
100 {
101 throw new IOException("Error while decrypting block.");
102 }
103 pos = 0;
104 }
105
106 public int read(byte[] dst) throws IOException
107 {
108 return read(dst, 0, dst.length);
109 }
110
111 public int read(byte[] dst, int off, int len) throws IOException
112 {
113 int count = 0;
114
115 while (len > 0)
116 {
117 if (pos >= blockSize)
118 {
119 getBlock();
120 }
121
122 int avail = blockSize - pos;
123 int copy = Math.min(avail, len);
124 System.arraycopy(buffer, pos, dst, off, copy);
125 pos += copy;
126 off += copy;
127 len -= copy;
128 count += copy;
129 }
130 return count;
131 }
132
133 public int read() throws IOException
134 {
135 if (pos >= blockSize)
136 {
137 getBlock();
138 }
139 return buffer[pos++] & 0xff;
140 }
141
142 public int readPlain(byte[] b, int off, int len) throws IOException
143 {
144 if (pos != blockSize)
145 {
146 throw new IOException("Cannot read plain since crypto buffer is not aligned.");
147 }
148 int n = 0;
149 while (n < len)
150 {
151 int cnt = internal_read(b, off + n, len - n);
152 if (cnt < 0)
153 {
154 throw new IOException("Cannot fill buffer, EOF reached.");
155 }
156 n += cnt;
157 }
158 return n;
159 }
160 }