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