Java Code Examples for javax.net.ssl.SSLEngineResult.Status#BUFFER_UNDERFLOW

The following examples show how to use javax.net.ssl.SSLEngineResult.Status#BUFFER_UNDERFLOW . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AsyncChannelWrapperSecure.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
private void checkResult(SSLEngineResult result, boolean wrap)
        throws SSLException {

    handshakeStatus = result.getHandshakeStatus();
    resultStatus = result.getStatus();

    if (resultStatus != Status.OK &&
            (wrap || resultStatus != Status.BUFFER_UNDERFLOW)) {
        throw new SSLException(
                sm.getString("asyncChannelWrapperSecure.check.notOk", resultStatus));
    }
    if (wrap && result.bytesConsumed() != 0) {
        throw new SSLException(sm.getString("asyncChannelWrapperSecure.check.wrap"));
    }
    if (!wrap && result.bytesProduced() != 0) {
        throw new SSLException(sm.getString("asyncChannelWrapperSecure.check.unwrap"));
    }
}
 
Example 2
Source File: SSLSocketChannel2.java    From Slyther with MIT License 6 votes vote down vote up
public SSLSocketChannel2( SocketChannel channel , SSLEngine sslEngine , ExecutorService exec , SelectionKey key ) throws IOException {
	if( channel == null || sslEngine == null || exec == null )
		throw new IllegalArgumentException( "parameter must not be null" );

	this.socketChannel = channel;
	this.sslEngine = sslEngine;
	this.exec = exec;

	readEngineResult = writeEngineResult = new SSLEngineResult( Status.BUFFER_UNDERFLOW, sslEngine.getHandshakeStatus(), 0, 0 ); // init to prevent NPEs

	tasks = new ArrayList<Future<?>>( 3 );
	if( key != null ) {
		key.interestOps( key.interestOps() | SelectionKey.OP_WRITE );
		this.selectionKey = key;
	}
	createBuffers( sslEngine.getSession() );
	// kick off handshake
	socketChannel.write( wrap( emptybuffer ) );// initializes res
	processHandshake();
}
 
Example 3
Source File: AsyncChannelWrapperSecure.java    From Tomcat7.0.67 with Apache License 2.0 6 votes vote down vote up
private void checkResult(SSLEngineResult result, boolean wrap)
        throws SSLException {

    handshakeStatus = result.getHandshakeStatus();
    resultStatus = result.getStatus();

    if (resultStatus != Status.OK &&
            (wrap || resultStatus != Status.BUFFER_UNDERFLOW)) {
        throw new SSLException("TODO");
    }
    if (wrap && result.bytesConsumed() != 0) {
        throw new SSLException("TODO");
    }
    if (!wrap && result.bytesProduced() != 0) {
        throw new SSLException("TODO");
    }
}
 
Example 4
Source File: SSLSocketChannel2.java    From RipplePower with Apache License 2.0 6 votes vote down vote up
public SSLSocketChannel2( SocketChannel channel , SSLEngine sslEngine , ExecutorService exec , SelectionKey key ) throws IOException {
	if( channel == null || sslEngine == null || exec == null )
		throw new IllegalArgumentException( "parameter must not be null" );

	this.socketChannel = channel;
	this.sslEngine = sslEngine;
	this.exec = exec;

	readEngineResult = writeEngineResult = new SSLEngineResult( Status.BUFFER_UNDERFLOW, sslEngine.getHandshakeStatus(), 0, 0 ); // init to prevent NPEs

	tasks = new ArrayList<Future<?>>( 3 );
	if( key != null ) {
		key.interestOps( key.interestOps() | SelectionKey.OP_WRITE );
		this.selectionKey = key;
	}
	createBuffers( sslEngine.getSession() );
	// kick off handshake
	socketChannel.write( wrap( emptybuffer ) );// initializes res
	processHandshake();
}
 
Example 5
Source File: AsyncChannelWrapperSecure.java    From tomcatsrc with Apache License 2.0 6 votes vote down vote up
private void checkResult(SSLEngineResult result, boolean wrap)
        throws SSLException {

    handshakeStatus = result.getHandshakeStatus();
    resultStatus = result.getStatus();

    if (resultStatus != Status.OK &&
            (wrap || resultStatus != Status.BUFFER_UNDERFLOW)) {
        throw new SSLException("TODO");
    }
    if (wrap && result.bytesConsumed() != 0) {
        throw new SSLException("TODO");
    }
    if (!wrap && result.bytesProduced() != 0) {
        throw new SSLException("TODO");
    }
}
 
Example 6
Source File: TLSWrapper.java    From Openfire with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the current status for this TLSHandler.
 *
 * @return the current TLSStatus
 */
public TLSStatus getStatus() {
    if (tlsEngineResult != null && tlsEngineResult.getStatus() == Status.BUFFER_UNDERFLOW) {
        return TLSStatus.UNDERFLOW;
    } else {
        if (tlsEngineResult != null && tlsEngineResult.getStatus() == Status.CLOSED) {
            return TLSStatus.CLOSED;
        } else {
            switch (tlsEngine.getHandshakeStatus()) {
            case NEED_WRAP:
                return TLSStatus.NEED_WRITE;
            case NEED_UNWRAP:
                return TLSStatus.NEED_READ;
            default:
                return TLSStatus.OK;
            }
        }
    }
}
 
Example 7
Source File: SqueakSSL.java    From trufflesqueak with MIT License 5 votes vote down vote up
private static void decryptOne(final SqSSL ssl, final ByteBuffer target) throws SSLException {
    ssl.buffer.flip();
    final SSLEngineResult result = unwrap(ssl, ssl.buffer, target);
    checkStatus("Decrypt status", result, Status.OK, Status.BUFFER_UNDERFLOW, Status.CLOSED);

    if (result.getStatus() == Status.OK || result.getStatus() == Status.BUFFER_UNDERFLOW) {
        ssl.buffer.compact();
    }

    if (result.getStatus() == Status.CLOSED) {
        connectionClosed(ssl);
    }
}
 
Example 8
Source File: SslHandler.java    From jane with GNU Lesser General Public License v3.0 5 votes vote down vote up
private void renegotiateIfNeeded(NextFilter nextFilter, SSLEngineResult res) throws Exception {
	if (res.getStatus() != Status.CLOSED && res.getStatus() != Status.BUFFER_UNDERFLOW
			&& res.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING) {
		// Renegotiation required.
		handshakeComplete = false;
		handshakeStatus = res.getHandshakeStatus();
		handshake(nextFilter);
	}
}
 
Example 9
Source File: SSLSocketChannel2.java    From clevertap-android-sdk with MIT License 4 votes vote down vote up
/**
   * Blocks when in blocking mode until at least one byte has been decoded.<br>
   * When not in blocking mode 0 may be returned.
   *
   * @return the number of bytes read.
   **/
  public int read(ByteBuffer dst) throws IOException {
      while (true) {
          if (!dst.hasRemaining())
              return 0;
          if (!isHandShakeComplete()) {
              if (isBlocking()) {
                  while (!isHandShakeComplete()) {
                      processHandshake();
                  }
              } else {
                  processHandshake();
                  if (!isHandShakeComplete()) {
                      return 0;
                  }
              }
          }
          // assert ( bufferallocations > 1 ); //see #190
          //if( bufferallocations <= 1 ) {
          //	createBuffers( sslEngine.getSession() );
          //}
/* 1. When "dst" is smaller than "inData" readRemaining will fill "dst" with data decoded in a previous read call.
 * 2. When "inCrypt" contains more data than "inData" has remaining space, unwrap has to be called on more time(readRemaining)
 */
          int purged = readRemaining(dst);
          if (purged != 0)
              return purged;

/* We only continue when we really need more data from the network.
 * Thats the case if inData is empty or inCrypt holds to less data than necessary for decryption
 */
          assert (inData.position() == 0);
          inData.clear();

          if (!inCrypt.hasRemaining())
              inCrypt.clear();
          else
              inCrypt.compact();

          if (isBlocking() || readEngineResult.getStatus() == Status.BUFFER_UNDERFLOW)
              if (socketChannel.read(inCrypt) == -1) {
                  return -1;
              }
          inCrypt.flip();
          unwrap();

          int transfered = transfereTo(inData, dst);
          if (transfered == 0 && isBlocking()) {
              continue;
          }
          return transfered;
      }
  }
 
Example 10
Source File: SSLSocketChannel.java    From nifi with Apache License 2.0 4 votes vote down vote up
private void performHandshake() throws IOException {
    // Generate handshake message
    final byte[] emptyMessage = new byte[0];
    handshaking = true;
    logger.debug("{} Performing Handshake", this);

    try {
        while (true) {
            switch (engine.getHandshakeStatus()) {
                case FINISHED:
                    return;
                case NEED_WRAP: {
                    final ByteBuffer appDataOut = ByteBuffer.wrap(emptyMessage);

                    final ByteBuffer outboundBuffer = streamOutManager.prepareForWrite(engine.getSession().getApplicationBufferSize());

                    final SSLEngineResult wrapHelloResult = engine.wrap(appDataOut, outboundBuffer);
                    if (wrapHelloResult.getStatus() == Status.BUFFER_OVERFLOW) {
                        streamOutManager.prepareForWrite(engine.getSession().getApplicationBufferSize());
                        continue;
                    }

                    if (wrapHelloResult.getStatus() != Status.OK) {
                        throw new SSLHandshakeException("Could not generate SSL Handshake information: SSLEngineResult: "
                                + wrapHelloResult.toString());
                    }

                    logger.trace("{} Handshake response after wrapping: {}", this, wrapHelloResult);

                    final ByteBuffer readableStreamOut = streamOutManager.prepareForRead(1);
                    final int bytesToSend = readableStreamOut.remaining();
                    writeFully(readableStreamOut);
                    logger.trace("{} Sent {} bytes of wrapped data for handshake", this, bytesToSend);

                    streamOutManager.clear();
                }
                continue;
                case NEED_UNWRAP: {
                    final ByteBuffer readableDataIn = streamInManager.prepareForRead(0);
                    final ByteBuffer appData = appDataManager.prepareForWrite(engine.getSession().getApplicationBufferSize());

                    // Read handshake response from other side
                    logger.trace("{} Unwrapping: {} to {}", this, readableDataIn, appData);
                    SSLEngineResult handshakeResponseResult = engine.unwrap(readableDataIn, appData);
                    logger.trace("{} Handshake response after unwrapping: {}", this, handshakeResponseResult);

                    if (handshakeResponseResult.getStatus() == Status.BUFFER_UNDERFLOW) {
                        final ByteBuffer writableDataIn = streamInManager.prepareForWrite(engine.getSession().getPacketBufferSize());
                        final int bytesRead = readData(writableDataIn);
                        if (bytesRead > 0) {
                            logger.trace("{} Read {} bytes for handshake", this, bytesRead);
                        }

                        if (bytesRead < 0) {
                            throw new SSLHandshakeException("Reached End-of-File marker while performing handshake");
                        }
                    } else if (handshakeResponseResult.getStatus() == Status.CLOSED) {
                        throw new IOException("Channel was closed by peer during handshake");
                    } else {
                        streamInManager.compact();
                        appDataManager.clear();
                    }
                }
                break;
                case NEED_TASK:
                    performTasks();
                    continue;
                case NOT_HANDSHAKING:
                    return;
            }
        }
    } finally {
        handshaking = false;
    }
}
 
Example 11
Source File: AsyncChannelWrapperSecure.java    From Tomcat7.0.67 with Apache License 2.0 4 votes vote down vote up
@Override
public void run() {
    int read = 0;

    boolean forceRead = false;

    try {
        while (read == 0) {
            socketReadBuffer.compact();

            if (forceRead) {
                Future<Integer> f =
                        socketChannel.read(socketReadBuffer);
                Integer socketRead = f.get();
                if (socketRead.intValue() == -1) {
                    throw new EOFException(sm.getString(
                            "asyncChannelWrapperSecure.eof"));
                }
            }

            socketReadBuffer.flip();

            if (socketReadBuffer.hasRemaining()) {
                // Decrypt the data in the buffer
                SSLEngineResult r =
                        sslEngine.unwrap(socketReadBuffer, dest);
                read += r.bytesProduced();
                Status s = r.getStatus();

                if (s == Status.OK) {
                    // Bytes available for reading and there may be
                    // sufficient data in the socketReadBuffer to
                    // support further reads without reading from the
                    // socket
                } else if (s == Status.BUFFER_UNDERFLOW) {
                    // There is partial data in the socketReadBuffer
                    if (read == 0) {
                        // Need more data before the partial data can be
                        // processed and some output generated
                        forceRead = true;
                    }
                    // else return the data we have and deal with the
                    // partial data on the next read
                } else if (s == Status.BUFFER_OVERFLOW) {
                    // Not enough space in the destination buffer to
                    // store all of the data. We could use a bytes read
                    // value of -bufferSizeRequired to signal the new
                    // buffer size required but an explicit exception is
                    // clearer.
                    if (reading.compareAndSet(true, false)) {
                        throw new ReadBufferOverflowException(sslEngine.
                                getSession().getApplicationBufferSize());
                    } else {
                        future.fail(new IllegalStateException(sm.getString(
                                "asyncChannelWrapperSecure.wrongStateRead")));
                    }
                } else {
                    // Status.CLOSED - unexpected
                    throw new IllegalStateException(sm.getString(
                            "asyncChannelWrapperSecure.statusUnwrap"));
                }

                // Check for tasks
                if (r.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
                    Runnable runnable = sslEngine.getDelegatedTask();
                    while (runnable != null) {
                        runnable.run();
                        runnable = sslEngine.getDelegatedTask();
                    }
                }
            } else {
                forceRead = true;
            }
        }


        if (reading.compareAndSet(true, false)) {
            future.complete(Integer.valueOf(read));
        } else {
            future.fail(new IllegalStateException(sm.getString(
                    "asyncChannelWrapperSecure.wrongStateRead")));
        }
    } catch (Exception e) {
        future.fail(e);
    }
}
 
Example 12
Source File: SSLSocketChannel2.java    From RipplePower with Apache License 2.0 4 votes vote down vote up
@Override
public boolean isNeedRead() {
	return inData.hasRemaining() || ( inCrypt.hasRemaining() && readEngineResult.getStatus() != Status.BUFFER_UNDERFLOW && readEngineResult.getStatus() != Status.CLOSED );
}
 
Example 13
Source File: SSLSocketChannel.java    From localization_nifi with Apache License 2.0 4 votes vote down vote up
private void performHandshake() throws IOException {
    // Generate handshake message
    final byte[] emptyMessage = new byte[0];
    handshaking = true;
    logger.debug("{} Performing Handshake", this);

    try {
        while (true) {
            switch (engine.getHandshakeStatus()) {
                case FINISHED:
                    return;
                case NEED_WRAP: {
                    final ByteBuffer appDataOut = ByteBuffer.wrap(emptyMessage);

                    final ByteBuffer outboundBuffer = streamOutManager.prepareForWrite(engine.getSession().getApplicationBufferSize());

                    final SSLEngineResult wrapHelloResult = engine.wrap(appDataOut, outboundBuffer);
                    if (wrapHelloResult.getStatus() == Status.BUFFER_OVERFLOW) {
                        streamOutManager.prepareForWrite(engine.getSession().getApplicationBufferSize());
                        continue;
                    }

                    if (wrapHelloResult.getStatus() != Status.OK) {
                        throw new SSLHandshakeException("Could not generate SSL Handshake information: SSLEngineResult: "
                                + wrapHelloResult.toString());
                    }

                    logger.trace("{} Handshake response after wrapping: {}", this, wrapHelloResult);

                    final ByteBuffer readableStreamOut = streamOutManager.prepareForRead(1);
                    final int bytesToSend = readableStreamOut.remaining();
                    writeFully(readableStreamOut);
                    logger.trace("{} Sent {} bytes of wrapped data for handshake", this, bytesToSend);

                    streamOutManager.clear();
                }
                continue;
                case NEED_UNWRAP: {
                    final ByteBuffer readableDataIn = streamInManager.prepareForRead(0);
                    final ByteBuffer appData = appDataManager.prepareForWrite(engine.getSession().getApplicationBufferSize());

                    // Read handshake response from other side
                    logger.trace("{} Unwrapping: {} to {}", this, readableDataIn, appData);
                    SSLEngineResult handshakeResponseResult = engine.unwrap(readableDataIn, appData);
                    logger.trace("{} Handshake response after unwrapping: {}", this, handshakeResponseResult);

                    if (handshakeResponseResult.getStatus() == Status.BUFFER_UNDERFLOW) {
                        final ByteBuffer writableDataIn = streamInManager.prepareForWrite(engine.getSession().getPacketBufferSize());
                        final int bytesRead = readData(writableDataIn);
                        if (bytesRead > 0) {
                            logger.trace("{} Read {} bytes for handshake", this, bytesRead);
                        }

                        if (bytesRead < 0) {
                            throw new SSLHandshakeException("Reached End-of-File marker while performing handshake");
                        }
                    } else if (handshakeResponseResult.getStatus() == Status.CLOSED) {
                        throw new IOException("Channel was closed by peer during handshake");
                    } else {
                        streamInManager.compact();
                        appDataManager.clear();
                    }
                }
                break;
                case NEED_TASK:
                    performTasks();
                    continue;
                case NOT_HANDSHAKING:
                    return;
            }
        }
    } finally {
        handshaking = false;
    }
}
 
Example 14
Source File: SSLStreams.java    From freehealth-connector with GNU Affero General Public License v3.0 4 votes vote down vote up
SSLStreams.WrapperResult recvAndUnwrap(ByteBuffer dst) throws IOException {
   Status status = Status.OK;
   SSLStreams.WrapperResult r = SSLStreams.this.new WrapperResult();
   r.buf = dst;
   if (this.closed) {
      throw new IOException("Engine is closed");
   } else {
      boolean needData;
      if (this.u_remaining > 0) {
         this.unwrap_src.compact();
         this.unwrap_src.flip();
         needData = false;
      } else {
         this.unwrap_src.clear();
         needData = true;
      }

      Object var5 = this.unwrapLock;
      synchronized(this.unwrapLock) {
         do {
            if (needData) {
               int x;
               do {
                  x = this.chan.read(this.unwrap_src);
               } while(x == 0);

               if (x == -1) {
                  throw new IOException("connection closed for reading");
               }

               this.unwrap_src.flip();
            }

            r.result = this.engine.unwrap(this.unwrap_src, r.buf);
            status = r.result.getStatus();
            if (status == Status.BUFFER_UNDERFLOW) {
               if (this.unwrap_src.limit() == this.unwrap_src.capacity()) {
                  this.unwrap_src = SSLStreams.this.realloc(this.unwrap_src, false, SSLStreams.BufType.PACKET);
               } else {
                  this.unwrap_src.position(this.unwrap_src.limit());
                  this.unwrap_src.limit(this.unwrap_src.capacity());
               }

               needData = true;
            } else if (status == Status.BUFFER_OVERFLOW) {
               r.buf = SSLStreams.this.realloc(r.buf, true, SSLStreams.BufType.APPLICATION);
               needData = false;
            } else if (status == Status.CLOSED) {
               this.closed = true;
               r.buf.flip();
               return r;
            }
         } while(status != Status.OK);
      }

      this.u_remaining = this.unwrap_src.remaining();
      return r;
   }
}
 
Example 15
Source File: SSLParser.java    From Voovan with Apache License 2.0 4 votes vote down vote up
/**
 * 读取SSL消息到缓冲区
 *
 * @return 接收数据大小
 * @throws IOException IO异常
 */
public synchronized int unWarpByteBufferChannel() throws IOException {
	ByteBufferChannel appByteBufferChannel = session.getReadByteBufferChannel();

	if(!isEnoughToUnwarp()) {
		return 0;
	}

	int readSize = 0;

	if (session.isConnected() && sslByteBufferChannel.size() > 0) {
		SSLEngineResult engineResult = null;

		try {
			while (true) {
				appData.clear();

				ByteBuffer byteBuffer = sslByteBufferChannel.getByteBuffer();;

				try {
					engineResult = unwarpData(byteBuffer, appData);
				} finally {
					sslByteBufferChannel.compact();
				}

				if (engineResult == null) {
					throw new SSLException("unWarpByteBufferChannel: Socket is disconnect");
				}

				appData.flip();
				appByteBufferChannel.writeEnd(appData);

				if (engineResult != null &&
						engineResult.getStatus() == Status.OK &&
						byteBuffer.remaining() == 0) {
					break;
				}

				if (engineResult != null &&
						(engineResult.getStatus() == Status.BUFFER_OVERFLOW ||
								engineResult.getStatus() == Status.BUFFER_UNDERFLOW ||
								engineResult.getStatus() == Status.CLOSED)
						) {
					break;
				}
			}
		}catch (MemoryReleasedException e){
			if(!session.isConnected()) {
				throw new SSLException("unWarpByteBufferChannel ", e);
			}
		}
	}
	return readSize;
}
 
Example 16
Source File: SSLStreams.java    From freehealth-connector with GNU Affero General Public License v3.0 4 votes vote down vote up
SSLStreams.WrapperResult recvAndUnwrap(ByteBuffer dst) throws IOException {
   Status status = Status.OK;
   SSLStreams.WrapperResult r = SSLStreams.this.new WrapperResult();
   r.buf = dst;
   if (this.closed) {
      throw new IOException("Engine is closed");
   } else {
      boolean needData;
      if (this.u_remaining > 0) {
         this.unwrap_src.compact();
         this.unwrap_src.flip();
         needData = false;
      } else {
         this.unwrap_src.clear();
         needData = true;
      }

      synchronized(this.unwrapLock) {
         do {
            if (needData) {
               int x;
               do {
                  x = this.chan.read(this.unwrap_src);
               } while(x == 0);

               if (x == -1) {
                  throw new IOException("connection closed for reading");
               }

               this.unwrap_src.flip();
            }

            r.result = this.engine.unwrap(this.unwrap_src, r.buf);
            status = r.result.getStatus();
            if (status == Status.BUFFER_UNDERFLOW) {
               if (this.unwrap_src.limit() == this.unwrap_src.capacity()) {
                  this.unwrap_src = SSLStreams.this.realloc(this.unwrap_src, false, SSLStreams.BufType.PACKET);
               } else {
                  this.unwrap_src.position(this.unwrap_src.limit());
                  this.unwrap_src.limit(this.unwrap_src.capacity());
               }

               needData = true;
            } else if (status == Status.BUFFER_OVERFLOW) {
               r.buf = SSLStreams.this.realloc(r.buf, true, SSLStreams.BufType.APPLICATION);
               needData = false;
            } else if (status == Status.CLOSED) {
               this.closed = true;
               r.buf.flip();
               return r;
            }
         } while(status != Status.OK);
      }

      this.u_remaining = this.unwrap_src.remaining();
      return r;
   }
}
 
Example 17
Source File: SslHandler.java    From netty4.0.27Learn with Apache License 2.0 4 votes vote down vote up
/**
 * Unwraps inbound SSL records.
 */
private void unwrap(
        ChannelHandlerContext ctx, ByteBuf packet, int offset, int length) throws SSLException {

    boolean wrapLater = false;
    boolean notifyClosure = false;
    ByteBuf decodeOut = allocate(ctx, length);
    try {
        for (;;) {
            final SSLEngineResult result = unwrap(engine, packet, offset, length, decodeOut);
            final Status status = result.getStatus();
            final HandshakeStatus handshakeStatus = result.getHandshakeStatus();
            final int produced = result.bytesProduced();
            final int consumed = result.bytesConsumed();

            // Update indexes for the next iteration
            offset += consumed;
            length -= consumed;

            if (status == Status.CLOSED) {
                // notify about the CLOSED state of the SSLEngine. See #137
                notifyClosure = true;
            }

            switch (handshakeStatus) {
                case NEED_UNWRAP:
                    break;
                case NEED_WRAP:
                    wrapNonAppData(ctx, true);
                    break;
                case NEED_TASK:
                    runDelegatedTasks();
                    break;
                case FINISHED:
                    setHandshakeSuccess();
                    wrapLater = true;
                    continue;
                case NOT_HANDSHAKING:
                    if (setHandshakeSuccessIfStillHandshaking()) {
                        wrapLater = true;
                        continue;
                    }
                    if (flushedBeforeHandshake) {
                        // We need to call wrap(...) in case there was a flush done before the handshake completed.
                        //
                        // See https://github.com/netty/netty/pull/2437
                        flushedBeforeHandshake = false;
                        wrapLater = true;
                    }

                    break;
                default:
                    throw new IllegalStateException("unknown handshake status: " + handshakeStatus);
            }

            if (status == Status.BUFFER_UNDERFLOW || consumed == 0 && produced == 0) {
                break;
            }
        }

        if (wrapLater) {
            wrap(ctx, true);
        }

        if (notifyClosure) {
            sslCloseFuture.trySuccess(ctx.channel());
        }
    } catch (SSLException e) {
        setHandshakeFailure(ctx, e);
        throw e;
    } finally {
        if (decodeOut.isReadable()) {
            ctx.fireChannelRead(decodeOut);
        } else {
            decodeOut.release();
        }
    }
}
 
Example 18
Source File: SSLSocketChannel2.java    From ans-android-sdk with GNU General Public License v3.0 4 votes vote down vote up
@Override
public boolean isNeedRead() {
    return inData.hasRemaining() || (inCrypt.hasRemaining()
            && readEngineResult.getStatus() != Status.BUFFER_UNDERFLOW
            && readEngineResult.getStatus() != Status.CLOSED);
}
 
Example 19
Source File: SSLSocketChannel2.java    From ans-android-sdk with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Blocks when in blocking mode until at least one byte has been decoded.<br>
 * When not in blocking mode 0 may be returned.
 *
 * @return the number of bytes read.
 **/
@Override
public int read(ByteBuffer dst) throws IOException {
    while (true) {
        if (!dst.hasRemaining()) {
            return 0;
        }
        if (!isHandShakeComplete()) {
            if (isBlocking()) {
                while (!isHandShakeComplete()) {
                    processHandshake();
                }
            } else {
                processHandshake();
                if (!isHandShakeComplete()) {
                    return 0;
                }
            }
        }
        // assert ( bufferallocations > 1 ); //see #190
        //if( bufferallocations <= 1 ) {
        //	createBuffers( sslEngine.getSession() );
        //}
        /* 1. When "dst" is smaller than "inData" readRemaining will fill "dst" with data
        decoded in a previous read call.
         * 2. When "inCrypt" contains more data than "inData" has remaining space, unwrap has
          * to be called on more time(readRemaining)
         */
        int purged = readRemaining(dst);
        if (purged != 0) {
            return purged;
        }

        /* We only continue when we really need more data from the network.
         * Thats the case if inData is empty or inCrypt holds to less data than necessary for
          * decryption
         */
        assert (inData.position() == 0);
        inData.clear();

        if (!inCrypt.hasRemaining()) {
            inCrypt.clear();
        } else {
            inCrypt.compact();
        }

        if (isBlocking() || readEngineResult.getStatus() == Status.BUFFER_UNDERFLOW) {
            if (socketChannel.read(inCrypt) == -1) {
                return -1;
            }
        }
        inCrypt.flip();
        unwrap();

        int transfered = transfereTo(inData, dst);
        if (transfered == 0 && isBlocking()) {
            continue;
        }
        return transfered;
    }
}
 
Example 20
Source File: AsyncChannelWrapperSecure.java    From tomcatsrc with Apache License 2.0 4 votes vote down vote up
@Override
public void run() {
    int read = 0;

    boolean forceRead = false;

    try {
        while (read == 0) {
            socketReadBuffer.compact();

            if (forceRead) {
                forceRead = false;
                Future<Integer> f = socketChannel.read(socketReadBuffer);
                Integer socketRead = f.get();
                if (socketRead.intValue() == -1) {
                    throw new EOFException(sm.getString(
                            "asyncChannelWrapperSecure.eof"));
                }
            }

            socketReadBuffer.flip();

            if (socketReadBuffer.hasRemaining()) {
                // Decrypt the data in the buffer
                SSLEngineResult r =
                        sslEngine.unwrap(socketReadBuffer, dest);
                read += r.bytesProduced();
                Status s = r.getStatus();

                if (s == Status.OK) {
                    // Bytes available for reading and there may be
                    // sufficient data in the socketReadBuffer to
                    // support further reads without reading from the
                    // socket
                } else if (s == Status.BUFFER_UNDERFLOW) {
                    // There is partial data in the socketReadBuffer
                    if (read == 0) {
                        // Need more data before the partial data can be
                        // processed and some output generated
                        forceRead = true;
                    }
                    // else return the data we have and deal with the
                    // partial data on the next read
                } else if (s == Status.BUFFER_OVERFLOW) {
                    // Not enough space in the destination buffer to
                    // store all of the data. We could use a bytes read
                    // value of -bufferSizeRequired to signal the new
                    // buffer size required but an explicit exception is
                    // clearer.
                    if (reading.compareAndSet(true, false)) {
                        throw new ReadBufferOverflowException(sslEngine.
                                getSession().getApplicationBufferSize());
                    } else {
                        future.fail(new IllegalStateException(sm.getString(
                                "asyncChannelWrapperSecure.wrongStateRead")));
                    }
                } else {
                    // Status.CLOSED - unexpected
                    throw new IllegalStateException(sm.getString(
                            "asyncChannelWrapperSecure.statusUnwrap"));
                }

                // Check for tasks
                if (r.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
                    Runnable runnable = sslEngine.getDelegatedTask();
                    while (runnable != null) {
                        runnable.run();
                        runnable = sslEngine.getDelegatedTask();
                    }
                }
            } else {
                forceRead = true;
            }
        }


        if (reading.compareAndSet(true, false)) {
            future.complete(Integer.valueOf(read));
        } else {
            future.fail(new IllegalStateException(sm.getString(
                    "asyncChannelWrapperSecure.wrongStateRead")));
        }
    } catch (Exception e) {
        future.fail(e);
    }
}