comparison app/src/main/java/ch/ethz/ssh2/crypto/cipher/CipherInputStream.java @ 438:d29cce60f393

migrate from Eclipse to Android Studio
author Carl Byington <carl@five-ten-sg.com>
date Thu, 03 Dec 2015 11:23:55 -0800
parents src/ch/ethz/ssh2/crypto/cipher/CipherInputStream.java@071eccdff8ea
children
comparison
equal deleted inserted replaced
437:208b31032318 438:d29cce60f393
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 BlockCipher currentCipher;
18 InputStream bi;
19 byte[] buffer;
20 byte[] enc;
21 int blockSize;
22 int pos;
23
24 /*
25 * We cannot use java.io.BufferedInputStream, since that is not available in
26 * J2ME. Everything could be improved alot here.
27 */
28
29 private static final int BUFF_SIZE = 8192;
30 byte[] input_buffer = new byte[BUFF_SIZE];
31 int input_buffer_pos = 0;
32 int input_buffer_size = 0;
33
34 public CipherInputStream(BlockCipher tc, InputStream bi) {
35 this.bi = bi;
36 changeCipher(tc);
37 }
38
39 private int fill_buffer() throws IOException {
40 input_buffer_pos = 0;
41 input_buffer_size = 0;
42 input_buffer_size = bi.read(input_buffer, 0, BUFF_SIZE);
43 return input_buffer_size;
44 }
45
46 private int internal_read(byte[] b, int off, int len) throws IOException {
47 if (input_buffer_size < 0) {
48 return -1;
49 }
50
51 if (input_buffer_pos >= input_buffer_size) {
52 if (fill_buffer() <= 0) {
53 return -1;
54 }
55 }
56
57 int avail = input_buffer_size - input_buffer_pos;
58 int thiscopy = (len > avail) ? avail : len;
59 System.arraycopy(input_buffer, input_buffer_pos, b, off, thiscopy);
60 input_buffer_pos += thiscopy;
61 return thiscopy;
62 }
63
64 public void changeCipher(BlockCipher bc) {
65 this.currentCipher = bc;
66 blockSize = bc.getBlockSize();
67 buffer = new byte[blockSize];
68 enc = new byte[blockSize];
69 pos = blockSize;
70 }
71
72 private void getBlock() throws IOException {
73 int n = 0;
74
75 while (n < blockSize) {
76 int len = internal_read(enc, n, blockSize - n);
77
78 if (len < 0) {
79 throw new IOException("Cannot read full block, EOF reached.");
80 }
81
82 n += len;
83 }
84
85 try {
86 currentCipher.transformBlock(enc, 0, buffer, 0);
87 }
88 catch (Exception e) {
89 throw new IOException("Error while decrypting block.");
90 }
91
92 pos = 0;
93 }
94
95 public int read(byte[] dst) throws IOException {
96 return read(dst, 0, dst.length);
97 }
98
99 public int read(byte[] dst, int off, int len) throws IOException {
100 int count = 0;
101
102 while (len > 0) {
103 if (pos >= blockSize) {
104 getBlock();
105 }
106
107 int avail = blockSize - pos;
108 int copy = Math.min(avail, len);
109 System.arraycopy(buffer, pos, dst, off, copy);
110 pos += copy;
111 off += copy;
112 len -= copy;
113 count += copy;
114 }
115
116 return count;
117 }
118
119 public int read() throws IOException {
120 if (pos >= blockSize) {
121 getBlock();
122 }
123
124 return buffer[pos++] & 0xff;
125 }
126
127 public int readPlain(byte[] b, int off, int len) throws IOException {
128 if (pos != blockSize) {
129 throw new IOException("Cannot read plain since crypto buffer is not aligned.");
130 }
131
132 int n = 0;
133
134 while (n < len) {
135 int cnt = internal_read(b, off + n, len - n);
136
137 if (cnt < 0) {
138 throw new IOException("Cannot fill buffer, EOF reached.");
139 }
140
141 n += cnt;
142 }
143
144 return n;
145 }
146 }