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