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 }