Mercurial > 510Connectbot
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 } |