Package org.conscrypt

Class HandshakeIODataStream

All Implemented Interfaces:
Closeable, AutoCloseable, Appendable, DataStream

public class HandshakeIODataStream
extends SSLInputStream
implements Appendable, DataStream
This class provides Input/Output data functionality for handshake layer. It provides read and write operations and accumulates all sent/received handshake's data. This class can be presented as a combination of 2 data pipes. The first data pipe is a pipe of income data: append method places the data at the beginning of the pipe, and read methods consume the data from the pipe. The second pipe is an outcoming data pipe: write operations plases the data into the pipe, and getData methods consume the data. It is important to note that work with pipe cound not be started if there is unconsumed data in another pipe. It is reasoned by the following: handshake protocol performs read and write operations consecuently. I.e. it first reads all income data and only than produces the responce and places it into the stream. The read operations of the stream presented by the methods of SSLInputStream which in its turn is an extension of InputStream. So this stream can be used as an InputStream parameter for certificate generation. Also input stream functionality supports marks. The marks help to reset the position of the stream in case of incompleate handshake records. Note that in case of exhausting of income data the EndOfBufferException is thown which implies the following: 1. the stream contains scrappy handshake record, 2. the read position should be reseted to marked, 3. and more income data is expected. The throwing of the exception (instead of returning of -1 value or incompleate filling of destination buffer) helps to speed up the process of scrappy data recognition and processing. For more information about TLS handshake process see TLS v 1 specification at http://www.ietf.org/rfc/rfc2246.txt.
  • Constructor Summary

    Constructors
    Constructor Description
    HandshakeIODataStream()  
  • Method Summary

    Modifier and Type Method Description
    void append​(byte[] src)
    Appends the income data to be read by handshake protocol.
    int available()
    Returns an estimated number of bytes that can be read or skipped without blocking for more input.
    protected void clearBuffer()  
    byte[] getData​(int length)
    returns the chunk of stored data with the length no more than specified.
    protected byte[] getDigestMD5()
    Returns the MD5 digest of the data passed throught the stream
    protected byte[] getDigestMD5withoutLast()
    Returns the MD5 digest of the data passed throught the stream except last message
    protected byte[] getDigestSHA()
    Returns the SHA-1 digest of the data passed throught the stream
    protected byte[] getDigestSHAwithoutLast()
    Returns the SHA-1 digest of the data passed throught the stream except last message
    protected byte[] getMessages()
    Returns all the data passed throught the stream
    boolean hasData()
    Checks if there is data to be read.
    void mark()  
    void mark​(int limit)
    Sets a mark position in this InputStream.
    boolean markSupported()
    Indicates whether this stream supports the mark() and reset() methods.
    int read()
    read an opaque value;
    int read​(byte[] dst, int offset, int length)
    Reads up to byteCount bytes from this stream and stores them in the byte array buffer starting at byteOffset.
    byte[] read​(int length)
    reads vector of opaque values
    protected void removeFromMarkedPosition()
    Removes the data from the marked position to the current read position.
    void reset()
    Resets this stream to the last marked location.
    void write​(byte b)
    Writes an opaque value
    void write​(byte[] vector)
    writes vector of opaque values
    void writeUint16​(long n)
    Writes Uint16 value
    void writeUint24​(long n)
    Writes Uint24 value
    void writeUint32​(long n)
    Writes Uint32 value
    void writeUint64​(long n)
    Writes Uint64 value
    void writeUint8​(long n)
    Writes Uint8 value

    Methods inherited from class org.conscrypt.SSLInputStream

    readUint16, readUint24, readUint32, readUint64, readUint8

    Methods inherited from class java.io.InputStream

    close, read, skip

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • HandshakeIODataStream

      public HandshakeIODataStream()
  • Method Details

    • available

      public int available()
      Description copied from class: InputStream
      Returns an estimated number of bytes that can be read or skipped without blocking for more input.

      Note that this method provides such a weak guarantee that it is not very useful in practice.

      Firstly, the guarantee is "without blocking for more input" rather than "without blocking": a read may still block waiting for I/O to complete — the guarantee is merely that it won't have to wait indefinitely for data to be written. The result of this method should not be used as a license to do I/O on a thread that shouldn't be blocked.

      Secondly, the result is a conservative estimate and may be significantly smaller than the actual number of bytes available. In particular, an implementation that always returns 0 would be correct. In general, callers should only use this method if they'd be satisfied with treating the result as a boolean yes or no answer to the question "is there definitely data ready?".

      Thirdly, the fact that a given number of bytes is "available" does not guarantee that a read or skip will actually read or skip that many bytes: they may read or skip fewer.

      It is particularly important to realize that you must not use this method to size a container and assume that you can read the entirety of the stream without needing to resize the container. Such callers should probably write everything they read to a ByteArrayOutputStream and convert that to a byte array. Alternatively, if you're reading from a file, File.length() returns the current length of the file (though assuming the file's length can't change may be incorrect, reading a file is inherently racy).

      The default implementation of this method in InputStream always returns 0. Subclasses should override this method if they are able to indicate the number of bytes available.

      Specified by:
      available in class SSLInputStream
      Returns:
      the estimated number of bytes available
    • markSupported

      public boolean markSupported()
      Description copied from class: InputStream
      Indicates whether this stream supports the mark() and reset() methods. The default implementation returns false.
      Overrides:
      markSupported in class InputStream
      Returns:
      always false.
      See Also:
      InputStream.mark(int), InputStream.reset()
    • mark

      public void mark​(int limit)
      Description copied from class: InputStream
      Sets a mark position in this InputStream. The parameter readlimit indicates how many bytes can be read before the mark is invalidated. Sending reset() will reposition the stream back to the marked position provided readLimit has not been surpassed.

      This default implementation does nothing and concrete subclasses must provide their own implementation.

      Overrides:
      mark in class InputStream
      Parameters:
      limit - the number of bytes that can be read from this stream before the mark is invalidated.
      See Also:
      InputStream.markSupported(), InputStream.reset()
    • mark

      public void mark()
    • reset

      public void reset()
      Description copied from class: InputStream
      Resets this stream to the last marked location. Throws an IOException if the number of bytes read since the mark has been set is greater than the limit provided to mark, or if no mark has been set.

      This implementation always throws an IOException and concrete subclasses should provide the proper implementation.

      Overrides:
      reset in class InputStream
    • removeFromMarkedPosition

      protected void removeFromMarkedPosition()
      Removes the data from the marked position to the current read position. The method is usefull when it is needed to delete one message from the internal buffer.
    • read

      public int read() throws IOException
      read an opaque value;
      Specified by:
      read in class SSLInputStream
      Parameters:
      byte - : byte
      Returns:
      Throws:
      IOException - if the stream is closed or another IOException occurs.
      See Also:
      SSLStreamedInput.read(), SSLBufferedInput.read(), read()
    • read

      public byte[] read​(int length) throws IOException
      reads vector of opaque values
      Overrides:
      read in class SSLInputStream
      Parameters:
      new - : long
      Returns:
      Throws:
      IOException - if read operation could not be finished.
    • read

      public int read​(byte[] dst, int offset, int length) throws IOException
      Description copied from class: InputStream
      Reads up to byteCount bytes from this stream and stores them in the byte array buffer starting at byteOffset. Returns the number of bytes actually read or -1 if the end of the stream has been reached.
      Overrides:
      read in class SSLInputStream
      Throws:
      IOException - if the stream is closed or another IOException occurs.
    • append

      public void append​(byte[] src)
      Appends the income data to be read by handshake protocol. The attempts to overflow the buffer by means of this methods seem to be futile because of: 1. The SSL protocol specifies the maximum size of the record and record protocol does not pass huge messages. (see TLS v1 specification http://www.ietf.org/rfc/rfc2246.txt , p 6.2) 2. After each call of this method, handshake protocol should start (and starts) the operations on received data and recognize the fake data if such was provided (to check the size of certificate for example).
      Specified by:
      append in interface Appendable
      Parameters:
      src - the source data to be appended.
    • clearBuffer

      protected void clearBuffer()
    • write

      public void write​(byte b)
      Writes an opaque value
      Parameters:
      byte - : byte
    • writeUint8

      public void writeUint8​(long n)
      Writes Uint8 value
      Parameters:
      long - : the value to be written (last byte)
    • writeUint16

      public void writeUint16​(long n)
      Writes Uint16 value
      Parameters:
      long - : the value to be written (last 2 bytes)
    • writeUint24

      public void writeUint24​(long n)
      Writes Uint24 value
      Parameters:
      long - : the value to be written (last 3 bytes)
    • writeUint32

      public void writeUint32​(long n)
      Writes Uint32 value
      Parameters:
      long - : the value to be written (last 4 bytes)
    • writeUint64

      public void writeUint64​(long n)
      Writes Uint64 value
      Parameters:
      long - : the value to be written
    • write

      public void write​(byte[] vector)
      writes vector of opaque values
      Parameters:
      vector - the vector to be written
    • hasData

      public boolean hasData()
      Description copied from interface: DataStream
      Checks if there is data to be read.
      Specified by:
      hasData in interface DataStream
      Returns:
      true if there is the input data in the stream, false otherwise
    • getData

      public byte[] getData​(int length)
      returns the chunk of stored data with the length no more than specified.
      Specified by:
      getData in interface DataStream
      Parameters:
      length - : int
      Returns:
    • getDigestMD5

      protected byte[] getDigestMD5()
      Returns the MD5 digest of the data passed throught the stream
      Returns:
      MD5 digest
    • getDigestSHA

      protected byte[] getDigestSHA()
      Returns the SHA-1 digest of the data passed throught the stream
      Returns:
      SHA-1 digest
    • getDigestMD5withoutLast

      protected byte[] getDigestMD5withoutLast()
      Returns the MD5 digest of the data passed throught the stream except last message
      Returns:
      MD5 digest
    • getDigestSHAwithoutLast

      protected byte[] getDigestSHAwithoutLast()
      Returns the SHA-1 digest of the data passed throught the stream except last message
      Returns:
      SHA-1 digest
    • getMessages

      protected byte[] getMessages()
      Returns all the data passed throught the stream
      Returns:
      all the data passed throught the stream at the moment