Mercurial > 510Connectbot
comparison src/com/trilead/ssh2/crypto/cipher/CipherInputStream.java @ 0:0ce5cc452d02
initial version
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 22 May 2014 10:41:19 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:0ce5cc452d02 |
---|---|
1 | |
2 package com.trilead.ssh2.crypto.cipher; | |
3 | |
4 import java.io.IOException; | |
5 import java.io.InputStream; | |
6 | |
7 /** | |
8 * CipherInputStream. | |
9 * | |
10 * @author Christian Plattner, plattner@trilead.com | |
11 * @version $Id: CipherInputStream.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $ | |
12 */ | |
13 public class CipherInputStream { | |
14 BlockCipher currentCipher; | |
15 InputStream bi; | |
16 byte[] buffer; | |
17 byte[] enc; | |
18 int blockSize; | |
19 int pos; | |
20 | |
21 /* | |
22 * We cannot use java.io.BufferedInputStream, since that is not available in | |
23 * J2ME. Everything could be improved alot here. | |
24 */ | |
25 | |
26 final int BUFF_SIZE = 2048; | |
27 byte[] input_buffer = new byte[BUFF_SIZE]; | |
28 int input_buffer_pos = 0; | |
29 int input_buffer_size = 0; | |
30 | |
31 public CipherInputStream(BlockCipher tc, InputStream bi) { | |
32 this.bi = bi; | |
33 changeCipher(tc); | |
34 } | |
35 | |
36 private int fill_buffer() throws IOException { | |
37 input_buffer_pos = 0; | |
38 input_buffer_size = bi.read(input_buffer, 0, BUFF_SIZE); | |
39 return input_buffer_size; | |
40 } | |
41 | |
42 private int internal_read(byte[] b, int off, int len) throws IOException { | |
43 if (input_buffer_size < 0) | |
44 return -1; | |
45 | |
46 if (input_buffer_pos >= input_buffer_size) { | |
47 if (fill_buffer() <= 0) | |
48 return -1; | |
49 } | |
50 | |
51 int avail = input_buffer_size - input_buffer_pos; | |
52 int thiscopy = (len > avail) ? avail : len; | |
53 System.arraycopy(input_buffer, input_buffer_pos, b, off, thiscopy); | |
54 input_buffer_pos += thiscopy; | |
55 return thiscopy; | |
56 } | |
57 | |
58 public void changeCipher(BlockCipher bc) { | |
59 this.currentCipher = bc; | |
60 blockSize = bc.getBlockSize(); | |
61 buffer = new byte[blockSize]; | |
62 enc = new byte[blockSize]; | |
63 pos = blockSize; | |
64 } | |
65 | |
66 private void getBlock() throws IOException { | |
67 int n = 0; | |
68 | |
69 while (n < blockSize) { | |
70 int len = internal_read(enc, n, blockSize - n); | |
71 | |
72 if (len < 0) | |
73 throw new IOException("Cannot read full block, EOF reached."); | |
74 | |
75 n += len; | |
76 } | |
77 | |
78 try { | |
79 currentCipher.transformBlock(enc, 0, buffer, 0); | |
80 } | |
81 catch (Exception e) { | |
82 throw new IOException("Error while decrypting block."); | |
83 } | |
84 | |
85 pos = 0; | |
86 } | |
87 | |
88 public int read(byte[] dst) throws IOException { | |
89 return read(dst, 0, dst.length); | |
90 } | |
91 | |
92 public int read(byte[] dst, int off, int len) throws IOException { | |
93 int count = 0; | |
94 | |
95 while (len > 0) { | |
96 if (pos >= blockSize) | |
97 getBlock(); | |
98 | |
99 int avail = blockSize - pos; | |
100 int copy = Math.min(avail, len); | |
101 System.arraycopy(buffer, pos, dst, off, copy); | |
102 pos += copy; | |
103 off += copy; | |
104 len -= copy; | |
105 count += copy; | |
106 } | |
107 | |
108 return count; | |
109 } | |
110 | |
111 public int read() throws IOException { | |
112 if (pos >= blockSize) { | |
113 getBlock(); | |
114 } | |
115 | |
116 return buffer[pos++] & 0xff; | |
117 } | |
118 | |
119 public int readPlain(byte[] b, int off, int len) throws IOException { | |
120 if (pos != blockSize) | |
121 throw new IOException("Cannot read plain since crypto buffer is not aligned."); | |
122 | |
123 int n = 0; | |
124 | |
125 while (n < len) { | |
126 int cnt = internal_read(b, off + n, len - n); | |
127 | |
128 if (cnt < 0) | |
129 throw new IOException("Cannot fill buffer, EOF reached."); | |
130 | |
131 n += cnt; | |
132 } | |
133 | |
134 return n; | |
135 } | |
136 } |