mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8187443: Forest Consolidation: Move files to unified layout
Reviewed-by: darcy, ihse
This commit is contained in:
parent
270fe13182
commit
3789983e89
56923 changed files with 3 additions and 15727 deletions
338
src/java.base/share/classes/javax/crypto/CipherInputStream.java
Normal file
338
src/java.base/share/classes/javax/crypto/CipherInputStream.java
Normal file
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.crypto;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.IllegalBlockSizeException;
|
||||
|
||||
/**
|
||||
* A CipherInputStream is composed of an InputStream and a Cipher so
|
||||
* that read() methods return data that are read in from the
|
||||
* underlying InputStream but have been additionally processed by the
|
||||
* Cipher. The Cipher must be fully initialized before being used by
|
||||
* a CipherInputStream.
|
||||
*
|
||||
* <p> For example, if the Cipher is initialized for decryption, the
|
||||
* CipherInputStream will attempt to read in data and decrypt them,
|
||||
* before returning the decrypted data.
|
||||
*
|
||||
* <p> This class adheres strictly to the semantics, especially the
|
||||
* failure semantics, of its ancestor classes
|
||||
* java.io.FilterInputStream and java.io.InputStream. This class has
|
||||
* exactly those methods specified in its ancestor classes, and
|
||||
* overrides them all. Moreover, this class catches all exceptions
|
||||
* that are not thrown by its ancestor classes. In particular, the
|
||||
* <code>skip</code> method skips, and the <code>available</code>
|
||||
* method counts only data that have been processed by the encapsulated Cipher.
|
||||
*
|
||||
* <p> It is crucial for a programmer using this class not to use
|
||||
* methods that are not defined or overriden in this class (such as a
|
||||
* new method or constructor that is later added to one of the super
|
||||
* classes), because the design and implementation of those methods
|
||||
* are unlikely to have considered security impact with regard to
|
||||
* CipherInputStream.
|
||||
*
|
||||
* @author Li Gong
|
||||
* @see java.io.InputStream
|
||||
* @see java.io.FilterInputStream
|
||||
* @see javax.crypto.Cipher
|
||||
* @see javax.crypto.CipherOutputStream
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public class CipherInputStream extends FilterInputStream {
|
||||
|
||||
// the cipher engine to use to process stream data
|
||||
private Cipher cipher;
|
||||
|
||||
// the underlying input stream
|
||||
private InputStream input;
|
||||
|
||||
/* the buffer holding data that have been read in from the
|
||||
underlying stream, but have not been processed by the cipher
|
||||
engine. the size 512 bytes is somewhat randomly chosen */
|
||||
private byte[] ibuffer = new byte[512];
|
||||
|
||||
// having reached the end of the underlying input stream
|
||||
private boolean done = false;
|
||||
|
||||
/* the buffer holding data that have been processed by the cipher
|
||||
engine, but have not been read out */
|
||||
private byte[] obuffer;
|
||||
// the offset pointing to the next "new" byte
|
||||
private int ostart = 0;
|
||||
// the offset pointing to the last "new" byte
|
||||
private int ofinish = 0;
|
||||
// stream status
|
||||
private boolean closed = false;
|
||||
|
||||
/*
|
||||
* private convenience function.
|
||||
*
|
||||
* Entry condition: ostart = ofinish
|
||||
*
|
||||
* Exit condition: ostart <= ofinish
|
||||
*
|
||||
* return (ofinish-ostart) (we have this many bytes for you)
|
||||
* return 0 (no data now, but could have more later)
|
||||
* return -1 (absolutely no more data)
|
||||
*
|
||||
* Note: Exceptions are only thrown after the stream is completely read.
|
||||
* For AEAD ciphers a read() of any length will internally cause the
|
||||
* whole stream to be read fully and verify the authentication tag before
|
||||
* returning decrypted data or exceptions.
|
||||
*/
|
||||
private int getMoreData() throws IOException {
|
||||
if (done) return -1;
|
||||
int readin = input.read(ibuffer);
|
||||
if (readin == -1) {
|
||||
done = true;
|
||||
try {
|
||||
obuffer = cipher.doFinal();
|
||||
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
||||
obuffer = null;
|
||||
throw new IOException(e);
|
||||
}
|
||||
if (obuffer == null)
|
||||
return -1;
|
||||
else {
|
||||
ostart = 0;
|
||||
ofinish = obuffer.length;
|
||||
return ofinish;
|
||||
}
|
||||
}
|
||||
try {
|
||||
obuffer = cipher.update(ibuffer, 0, readin);
|
||||
} catch (IllegalStateException e) {
|
||||
obuffer = null;
|
||||
throw e;
|
||||
}
|
||||
ostart = 0;
|
||||
if (obuffer == null)
|
||||
ofinish = 0;
|
||||
else ofinish = obuffer.length;
|
||||
return ofinish;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a CipherInputStream from an InputStream and a
|
||||
* Cipher.
|
||||
* <br>Note: if the specified input stream or cipher is
|
||||
* null, a NullPointerException may be thrown later when
|
||||
* they are used.
|
||||
* @param is the to-be-processed input stream
|
||||
* @param c an initialized Cipher object
|
||||
*/
|
||||
public CipherInputStream(InputStream is, Cipher c) {
|
||||
super(is);
|
||||
input = is;
|
||||
cipher = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a CipherInputStream from an InputStream without
|
||||
* specifying a Cipher. This has the effect of constructing a
|
||||
* CipherInputStream using a NullCipher.
|
||||
* <br>Note: if the specified input stream is null, a
|
||||
* NullPointerException may be thrown later when it is used.
|
||||
* @param is the to-be-processed input stream
|
||||
*/
|
||||
protected CipherInputStream(InputStream is) {
|
||||
super(is);
|
||||
input = is;
|
||||
cipher = new NullCipher();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next byte of data from this input stream. The value
|
||||
* byte is returned as an <code>int</code> in the range
|
||||
* <code>0</code> to <code>255</code>. If no byte is available
|
||||
* because the end of the stream has been reached, the value
|
||||
* <code>-1</code> is returned. This method blocks until input data
|
||||
* is available, the end of the stream is detected, or an exception
|
||||
* is thrown.
|
||||
*
|
||||
* @return the next byte of data, or <code>-1</code> if the end of the
|
||||
* stream is reached.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
if (ostart >= ofinish) {
|
||||
// we loop for new data as the spec says we are blocking
|
||||
int i = 0;
|
||||
while (i == 0) i = getMoreData();
|
||||
if (i == -1) return -1;
|
||||
}
|
||||
return ((int) obuffer[ostart++] & 0xff);
|
||||
};
|
||||
|
||||
/**
|
||||
* Reads up to <code>b.length</code> bytes of data from this input
|
||||
* stream into an array of bytes.
|
||||
* <p>
|
||||
* The <code>read</code> method of <code>InputStream</code> calls
|
||||
* the <code>read</code> method of three arguments with the arguments
|
||||
* <code>b</code>, <code>0</code>, and <code>b.length</code>.
|
||||
*
|
||||
* @param b the buffer into which the data is read.
|
||||
* @return the total number of bytes read into the buffer, or
|
||||
* <code>-1</code> is there is no more data because the end of
|
||||
* the stream has been reached.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
* @see java.io.InputStream#read(byte[], int, int)
|
||||
*/
|
||||
public int read(byte b[]) throws IOException {
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to <code>len</code> bytes of data from this input stream
|
||||
* into an array of bytes. This method blocks until some input is
|
||||
* available. If the first argument is <code>null,</code> up to
|
||||
* <code>len</code> bytes are read and discarded.
|
||||
*
|
||||
* @param b the buffer into which the data is read.
|
||||
* @param off the start offset in the destination array
|
||||
* <code>buf</code>
|
||||
* @param len the maximum number of bytes read.
|
||||
* @return the total number of bytes read into the buffer, or
|
||||
* <code>-1</code> if there is no more data because the end of
|
||||
* the stream has been reached.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
* @see java.io.InputStream#read()
|
||||
*/
|
||||
public int read(byte b[], int off, int len) throws IOException {
|
||||
if (ostart >= ofinish) {
|
||||
// we loop for new data as the spec says we are blocking
|
||||
int i = 0;
|
||||
while (i == 0) i = getMoreData();
|
||||
if (i == -1) return -1;
|
||||
}
|
||||
if (len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
int available = ofinish - ostart;
|
||||
if (len < available) available = len;
|
||||
if (b != null) {
|
||||
System.arraycopy(obuffer, ostart, b, off, available);
|
||||
}
|
||||
ostart = ostart + available;
|
||||
return available;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips <code>n</code> bytes of input from the bytes that can be read
|
||||
* from this input stream without blocking.
|
||||
*
|
||||
* <p>Fewer bytes than requested might be skipped.
|
||||
* The actual number of bytes skipped is equal to <code>n</code> or
|
||||
* the result of a call to
|
||||
* {@link #available() available},
|
||||
* whichever is smaller.
|
||||
* If <code>n</code> is less than zero, no bytes are skipped.
|
||||
*
|
||||
* <p>The actual number of bytes skipped is returned.
|
||||
*
|
||||
* @param n the number of bytes to be skipped.
|
||||
* @return the actual number of bytes skipped.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public long skip(long n) throws IOException {
|
||||
int available = ofinish - ostart;
|
||||
if (n > available) {
|
||||
n = available;
|
||||
}
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
}
|
||||
ostart += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes that can be read from this input
|
||||
* stream without blocking. The <code>available</code> method of
|
||||
* <code>InputStream</code> returns <code>0</code>. This method
|
||||
* <B>should</B> be overridden by subclasses.
|
||||
*
|
||||
* @return the number of bytes that can be read from this input stream
|
||||
* without blocking.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public int available() throws IOException {
|
||||
return (ofinish - ostart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this input stream and releases any system resources
|
||||
* associated with the stream.
|
||||
* <p>
|
||||
* The <code>close</code> method of <code>CipherInputStream</code>
|
||||
* calls the <code>close</code> method of its underlying input
|
||||
* stream.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
closed = true;
|
||||
input.close();
|
||||
|
||||
// Throw away the unprocessed data and throw no crypto exceptions.
|
||||
// AEAD ciphers are fully readed before closing. Any authentication
|
||||
// exceptions would occur while reading.
|
||||
if (!done) {
|
||||
try {
|
||||
cipher.doFinal();
|
||||
}
|
||||
catch (BadPaddingException | IllegalBlockSizeException ex) {
|
||||
// Catch exceptions as the rest of the stream is unused.
|
||||
}
|
||||
}
|
||||
ostart = 0;
|
||||
ofinish = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if this input stream supports the <code>mark</code>
|
||||
* and <code>reset</code> methods, which it does not.
|
||||
*
|
||||
* @return <code>false</code>, since this class does not support the
|
||||
* <code>mark</code> and <code>reset</code> methods.
|
||||
* @see java.io.InputStream#mark(int)
|
||||
* @see java.io.InputStream#reset()
|
||||
*/
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue