1 2 package ch.ethz.ssh2.crypto.cipher; 3 4 import java.io.IOException ; 5 import java.io.InputStream ; 6 7 13 public class CipherInputStream 14 { 15 BlockCipher currentCipher; 16 InputStream bi; 17 byte[] buffer; 18 byte[] enc; 19 int blockSize; 20 int pos; 21 22 26 27 final int BUFF_SIZE = 2048; 28 byte[] input_buffer = new byte[BUFF_SIZE]; 29 int input_buffer_pos = 0; 30 int input_buffer_size = 0; 31 32 public CipherInputStream(BlockCipher tc, InputStream bi) 33 { 34 this.bi = bi; 35 changeCipher(tc); 36 } 37 38 private int fill_buffer() throws IOException 39 { 40 input_buffer_pos = 0; 41 input_buffer_size = bi.read(input_buffer, 0, BUFF_SIZE); 42 return input_buffer_size; 43 } 44 45 private int internal_read(byte[] b, int off, int len) throws IOException 46 { 47 if (input_buffer_size < 0) 48 return -1; 49 50 if (input_buffer_pos >= input_buffer_size) 51 { 52 if (fill_buffer() <= 0) 53 return -1; 54 } 55 56 int avail = input_buffer_size - input_buffer_pos; 57 int thiscopy = (len > avail) ? avail : len; 58 59 System.arraycopy(input_buffer, input_buffer_pos, b, off, thiscopy); 60 input_buffer_pos += thiscopy; 61 62 return thiscopy; 63 } 64 65 public void changeCipher(BlockCipher bc) 66 { 67 this.currentCipher = bc; 68 blockSize = bc.getBlockSize(); 69 buffer = new byte[blockSize]; 70 enc = new byte[blockSize]; 71 pos = blockSize; 72 } 73 74 private void getBlock() throws IOException 75 { 76 int n = 0; 77 while (n < blockSize) 78 { 79 int len = internal_read(enc, n, blockSize - n); 80 if (len < 0) 81 throw new IOException ("Cannot read full block, EOF reached."); 82 n += len; 83 } 84 85 try 86 { 87 currentCipher.transformBlock(enc, 0, buffer, 0); 88 } 89 catch (Exception e) 90 { 91 throw new IOException ("Error while decrypting block."); 92 } 93 pos = 0; 94 } 95 96 public int read(byte[] dst) throws IOException 97 { 98 return read(dst, 0, dst.length); 99 } 100 101 public int read(byte[] dst, int off, int len) throws IOException 102 { 103 int count = 0; 104 105 while (len > 0) 106 { 107 if (pos >= blockSize) 108 getBlock(); 109 110 int avail = blockSize - pos; 111 int copy = Math.min(avail, len); 112 System.arraycopy(buffer, pos, dst, off, copy); 113 pos += copy; 114 off += copy; 115 len -= copy; 116 count += copy; 117 } 118 return count; 119 } 120 121 public int read() throws IOException 122 { 123 if (pos >= blockSize) 124 { 125 getBlock(); 126 } 127 return buffer[pos++] & 0xff; 128 } 129 130 public int readPlain(byte[] b, int off, int len) throws IOException 131 { 132 if (pos != blockSize) 133 throw new IOException ("Cannot read plain since crypto buffer is not aligned."); 134 int n = 0; 135 while (n < len) 136 { 137 int cnt = internal_read(b, off + n, len - n); 138 if (cnt < 0) 139 throw new IOException ("Cannot fill buffer, EOF reached."); 140 n += cnt; 141 } 142 return n; 143 } 144 } 145 | Popular Tags |