001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Alexander Y. Kleymenov
020: * @version $Revision$
021: */package javax.crypto;
022:
023: import java.io.FilterInputStream;
024: import java.io.IOException;
025: import java.io.InputStream;
026: import javax.crypto.NullCipher;
027: import java.security.GeneralSecurityException;
028:
029: /**
030: * @com.intel.drl.spec_ref
031: */
032: public class CipherInputStream extends FilterInputStream {
033:
034: private final Cipher cipher;
035: private final int I_BUFFER_SIZE = 20;
036: private final byte[] i_buffer = new byte[I_BUFFER_SIZE];
037: private int index; // index of the bytes to return from o_buffer
038: private byte[] o_buffer;
039: private boolean finished;
040:
041: /**
042: * @com.intel.drl.spec_ref
043: */
044: public CipherInputStream(InputStream is, Cipher c) {
045: super (is);
046: this .cipher = c;
047: }
048:
049: /**
050: * @com.intel.drl.spec_ref
051: */
052: protected CipherInputStream(InputStream is) {
053: this (is, new NullCipher());
054: }
055:
056: /**
057: * @com.intel.drl.spec_ref
058: */
059: @Override
060: public int read() throws IOException {
061: if (finished) {
062: return ((o_buffer == null) || (index == o_buffer.length)) ? -1
063: : o_buffer[index++] & 0xFF;
064: }
065: if ((o_buffer != null) && (index < o_buffer.length)) {
066: return o_buffer[index++] & 0xFF;
067: }
068: index = 0;
069: o_buffer = null;
070: int num_read;
071: while (o_buffer == null) {
072: if ((num_read = in.read(i_buffer)) == -1) {
073: try {
074: o_buffer = cipher.doFinal();
075: } catch (Exception e) {
076: throw new IOException(e.getMessage());
077: }
078: finished = true;
079: break;
080: }
081: o_buffer = cipher.update(i_buffer, 0, num_read);
082: }
083: return read();
084: }
085:
086: /**
087: * @com.intel.drl.spec_ref
088: */
089: @Override
090: public int read(byte[] b) throws IOException {
091: return read(b, 0, b.length);
092: }
093:
094: /**
095: * @com.intel.drl.spec_ref
096: */
097: @Override
098: public int read(byte[] b, int off, int len) throws IOException {
099: if (in == null) {
100: throw new NullPointerException(
101: "Underlying input stream is null");
102: }
103:
104: int read_b;
105: int i;
106: for (i = 0; i < len; i++) {
107: if ((read_b = read()) == -1) {
108: return (i == 0) ? -1 : i;
109: }
110: if (b != null) {
111: b[off + i] = (byte) read_b;
112: }
113: }
114: return i;
115: }
116:
117: /**
118: * @com.intel.drl.spec_ref
119: */
120: @Override
121: public long skip(long n) throws IOException {
122: long i = 0;
123: int available = available();
124: if (available < n) {
125: n = available;
126: }
127: while ((i < n) && (read() != -1)) {
128: i++;
129: }
130: return i;
131: }
132:
133: /**
134: * @com.intel.drl.spec_ref
135: */
136: @Override
137: public int available() throws IOException {
138: return 0;
139: }
140:
141: /**
142: * @com.intel.drl.spec_ref
143: */
144: @Override
145: public void close() throws IOException {
146: in.close();
147: try {
148: cipher.doFinal();
149: } catch (GeneralSecurityException ignore) {
150: //do like RI does
151: }
152:
153: }
154:
155: /**
156: * @com.intel.drl.spec_ref
157: */
158: @Override
159: public boolean markSupported() {
160: return false;
161: }
162: }
|