Mercurial > 510Connectbot
comparison src/com/trilead/ssh2/crypto/cipher/CipherOutputStream.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.OutputStream; | |
6 | |
7 /** | |
8 * CipherOutputStream. | |
9 * | |
10 * @author Christian Plattner, plattner@trilead.com | |
11 * @version $Id: CipherOutputStream.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $ | |
12 */ | |
13 public class CipherOutputStream { | |
14 BlockCipher currentCipher; | |
15 OutputStream bo; | |
16 byte[] buffer; | |
17 byte[] enc; | |
18 int blockSize; | |
19 int pos; | |
20 | |
21 /* | |
22 * We cannot use java.io.BufferedOutputStream, since that is not available | |
23 * in J2ME. Everything could be improved here alot. | |
24 */ | |
25 | |
26 final int BUFF_SIZE = 2048; | |
27 byte[] out_buffer = new byte[BUFF_SIZE]; | |
28 int out_buffer_pos = 0; | |
29 | |
30 public CipherOutputStream(BlockCipher tc, OutputStream bo) { | |
31 this.bo = bo; | |
32 changeCipher(tc); | |
33 } | |
34 | |
35 private void internal_write(byte[] src, int off, int len) throws IOException { | |
36 while (len > 0) { | |
37 int space = BUFF_SIZE - out_buffer_pos; | |
38 int copy = (len > space) ? space : len; | |
39 System.arraycopy(src, off, out_buffer, out_buffer_pos, copy); | |
40 off += copy; | |
41 out_buffer_pos += copy; | |
42 len -= copy; | |
43 | |
44 if (out_buffer_pos >= BUFF_SIZE) { | |
45 bo.write(out_buffer, 0, BUFF_SIZE); | |
46 out_buffer_pos = 0; | |
47 } | |
48 } | |
49 } | |
50 | |
51 private void internal_write(int b) throws IOException { | |
52 out_buffer[out_buffer_pos++] = (byte) b; | |
53 | |
54 if (out_buffer_pos >= BUFF_SIZE) { | |
55 bo.write(out_buffer, 0, BUFF_SIZE); | |
56 out_buffer_pos = 0; | |
57 } | |
58 } | |
59 | |
60 public void flush() throws IOException { | |
61 if (pos != 0) | |
62 throw new IOException("FATAL: cannot flush since crypto buffer is not aligned."); | |
63 | |
64 if (out_buffer_pos > 0) { | |
65 bo.write(out_buffer, 0, out_buffer_pos); | |
66 out_buffer_pos = 0; | |
67 } | |
68 | |
69 bo.flush(); | |
70 } | |
71 | |
72 public void changeCipher(BlockCipher bc) { | |
73 this.currentCipher = bc; | |
74 blockSize = bc.getBlockSize(); | |
75 buffer = new byte[blockSize]; | |
76 enc = new byte[blockSize]; | |
77 pos = 0; | |
78 } | |
79 | |
80 private void writeBlock() throws IOException { | |
81 try { | |
82 currentCipher.transformBlock(buffer, 0, enc, 0); | |
83 } | |
84 catch (Exception e) { | |
85 throw(IOException) new IOException("Error while decrypting block.").initCause(e); | |
86 } | |
87 | |
88 internal_write(enc, 0, blockSize); | |
89 pos = 0; | |
90 } | |
91 | |
92 public void write(byte[] src, int off, int len) throws IOException { | |
93 while (len > 0) { | |
94 int avail = blockSize - pos; | |
95 int copy = Math.min(avail, len); | |
96 System.arraycopy(src, off, buffer, pos, copy); | |
97 pos += copy; | |
98 off += copy; | |
99 len -= copy; | |
100 | |
101 if (pos >= blockSize) | |
102 writeBlock(); | |
103 } | |
104 } | |
105 | |
106 public void write(int b) throws IOException { | |
107 buffer[pos++] = (byte) b; | |
108 | |
109 if (pos >= blockSize) | |
110 writeBlock(); | |
111 } | |
112 | |
113 public void writePlain(int b) throws IOException { | |
114 if (pos != 0) | |
115 throw new IOException("Cannot write plain since crypto buffer is not aligned."); | |
116 | |
117 internal_write(b); | |
118 } | |
119 | |
120 public void writePlain(byte[] b, int off, int len) throws IOException { | |
121 if (pos != 0) | |
122 throw new IOException("Cannot write plain since crypto buffer is not aligned."); | |
123 | |
124 internal_write(b, off, len); | |
125 } | |
126 } |