javax.net.ssl.SSLEngineResult#bytesConsumed ( )源码实例Demo

下面列出了javax.net.ssl.SSLEngineResult#bytesConsumed ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

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"));
    }
}
 
源代码2 项目: Tomcat8-Source-Read   文件: SecureNio2Channel.java
protected void wrap() {
    try {
        if (!netOutBuffer.hasRemaining()) {
            netOutBuffer.clear();
            SSLEngineResult result = sslEngine.wrap(src, netOutBuffer);
            written = result.bytesConsumed();
            netOutBuffer.flip();
            if (result.getStatus() == Status.OK) {
                if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK)
                    tasks();
            } else {
                t = new IOException(sm.getString("channel.nio.ssl.wrapFail", result.getStatus()));
            }
        }
        integer = sc.write(netOutBuffer);
    } catch (SSLException e) {
        t = e;
    }
}
 
源代码3 项目: pgadba   文件: TlsChannelImpl.java
private WrapResult wrapLoop(ByteBufferSet source) throws SSLException {
  while (true) {
    SSLEngineResult result = callEngineWrap(source);
    switch (result.getStatus()) {
      case OK:
      case CLOSED:
        return new WrapResult(result.bytesConsumed(), result.getHandshakeStatus());
      case BUFFER_OVERFLOW:
        Util.assertTrue(result.bytesConsumed() == 0);
        outEncrypted.enlarge();
        break;
      case BUFFER_UNDERFLOW:
        throw new IllegalStateException();
      default:
        throw new RuntimeException("reached default clause in switch");
    }
  }
}
 
源代码4 项目: tomcatsrc   文件: AsyncChannelWrapperSecure.java
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");
    }
}
 
/**
 * Try to flush out any existing outbound data, then try to wrap
 * anything new contained in the src buffer.
 * <p>
 * Return the number of bytes actually consumed from the buffer,
 * but the data may actually be still sitting in the output buffer,
 * waiting to be flushed.
 */
private int doWrite(ByteBuffer src) throws IOException {
    int retValue = 0;

    if (outNetBB.hasRemaining() && !tryFlush(outNetBB)) {
        return retValue;
    }

    /*
     * The data buffer is empty, we can reuse the entire buffer.
     */
    outNetBB.clear();

    SSLEngineResult result = sslEngine.wrap(src, outNetBB);
    retValue = result.bytesConsumed();

    outNetBB.flip();

    if (result.getStatus() == Status.OK) {
        if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
            doTasks();
        }
    } else {
        throw new IOException("sslEngine error during data write: " +
                result.getStatus());
    }

    /*
     * Try to flush the data, regardless of whether or not
     * it's been selected.  Odds of a write buffer being full
     * is less than a read buffer being empty.
     */
    tryFlush(src);
    if (outNetBB.hasRemaining()) {
        tryFlush(outNetBB);
    }

    return retValue;
}
 
@Override
public void run() {
    long written = 0;

    try {
        for (int i = offset; i < offset + length; i++) {
            ByteBuffer src = srcs[i];
            while (src.hasRemaining()) {
                socketWriteBuffer.clear();

                // Encrypt the data
                SSLEngineResult r = sslEngine.wrap(src, socketWriteBuffer);
                written += r.bytesConsumed();
                Status s = r.getStatus();

                if (s == Status.OK || s == Status.BUFFER_OVERFLOW) {
                    // Need to write out the bytes and may need to read from
                    // the source again to empty it
                } else {
                    // Status.BUFFER_UNDERFLOW - only happens on unwrap
                    // Status.CLOSED - unexpected
                    throw new IllegalStateException(sm.getString(
                            "asyncChannelWrapperSecure.statusWrap"));
                }

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

                socketWriteBuffer.flip();

                // Do the write
                int toWrite = r.bytesProduced();
                while (toWrite > 0) {
                    Future<Integer> f =
                            socketChannel.write(socketWriteBuffer);
                    Integer socketWrite = f.get();
                    toWrite -= socketWrite.intValue();
                }
            }
        }


        if (writing.compareAndSet(true, false)) {
            future.complete(Long.valueOf(written));
        } else {
            future.fail(new IllegalStateException(sm.getString(
                    "asyncChannelWrapperSecure.wrongStateWrite")));
        }
    } catch (Exception e) {
        writing.set(false);
        future.fail(e);
    }
}
 
源代码7 项目: netty-4.1.22   文件: SslHandler.java
/**
 * This method will not call
 * {@link #setHandshakeFailure(ChannelHandlerContext, Throwable, boolean, boolean, boolean)} or
 * {@link #setHandshakeFailure(ChannelHandlerContext, Throwable)}.
 * @return {@code true} if this method ends on {@link SSLEngineResult.HandshakeStatus#NOT_HANDSHAKING}.
 */
private boolean wrapNonAppData(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException {
    ByteBuf out = null;
    ByteBufAllocator alloc = ctx.alloc();
    try {
        // Only continue to loop if the handler was not removed in the meantime.
        // See https://github.com/netty/netty/issues/5860
        while (!ctx.isRemoved()) {
            if (out == null) {
                // As this is called for the handshake we have no real idea how big the buffer needs to be.
                // That said 2048 should give us enough room to include everything like ALPN / NPN data.
                // If this is not enough we will increase the buffer in wrap(...).
                out = allocateOutNetBuf(ctx, 2048, 1);
            }
            SSLEngineResult result = wrap(alloc, engine, Unpooled.EMPTY_BUFFER, out);

            if (result.bytesProduced() > 0) {
                ctx.write(out);
                if (inUnwrap) {
                    needsFlush = true;
                }
                out = null;
            }

            switch (result.getHandshakeStatus()) {
                case FINISHED:
                    setHandshakeSuccess();
                    return false;
                case NEED_TASK:
                    runDelegatedTasks();
                    break;
                case NEED_UNWRAP:
                    if (inUnwrap) {
                        // If we asked for a wrap, the engine requested an unwrap, and we are in unwrap there is
                        // no use in trying to call wrap again because we have already attempted (or will after we
                        // return) to feed more data to the engine.
                        return false;
                    }

                    unwrapNonAppData(ctx);
                    break;
                case NEED_WRAP:
                    break;
                case NOT_HANDSHAKING:
                    setHandshakeSuccessIfStillHandshaking();
                    // Workaround for TLS False Start problem reported at:
                    // https://github.com/netty/netty/issues/1108#issuecomment-14266970
                    if (!inUnwrap) {
                        unwrapNonAppData(ctx);
                    }
                    return true;
                default:
                    throw new IllegalStateException("Unknown handshake status: " + result.getHandshakeStatus());
            }

            if (result.bytesProduced() == 0) {
                break;
            }

            // It should not consume empty buffers when it is not handshaking
            // Fix for Android, where it was encrypting empty buffers even when not handshaking
            if (result.bytesConsumed() == 0 && result.getHandshakeStatus() == HandshakeStatus.NOT_HANDSHAKING) {
                break;
            }
        }
    }  finally {
        if (out != null) {
            out.release();
        }
    }
    return false;
}
 
源代码8 项目: netty-4.1.22   文件: OpenSslEngineTest.java
@Test
public void testBufferUnderFlowAvoidedIfJDKCompatabilityModeOff() throws Exception {
    SelfSignedCertificate cert = new SelfSignedCertificate();

    clientSslCtx = SslContextBuilder
            .forClient()
            .trustManager(cert.cert())
            .sslProvider(sslClientProvider())
            .build();
    SSLEngine client = clientSslCtx.newHandler(UnpooledByteBufAllocator.DEFAULT).engine();

    serverSslCtx = SslContextBuilder
            .forServer(cert.certificate(), cert.privateKey())
            .sslProvider(sslServerProvider())
            .build();
    SSLEngine server = serverSslCtx.newHandler(UnpooledByteBufAllocator.DEFAULT).engine();

    try {
        ByteBuffer plainClient = allocateBuffer(1024);
        plainClient.limit(plainClient.capacity());

        ByteBuffer encClientToServer = allocateBuffer(client.getSession().getPacketBufferSize());
        ByteBuffer plainServer = allocateBuffer(server.getSession().getApplicationBufferSize());

        handshake(client, server);

        SSLEngineResult result = client.wrap(plainClient, encClientToServer);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertEquals(result.bytesConsumed(), plainClient.capacity());

        // Flip so we can read it.
        encClientToServer.flip();
        int remaining = encClientToServer.remaining();

        // We limit the buffer so we have less then the header to read, this should result in an BUFFER_UNDERFLOW.
        encClientToServer.limit(SslUtils.SSL_RECORD_HEADER_LENGTH - 1);
        result = server.unwrap(encClientToServer, plainServer);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertEquals(SslUtils.SSL_RECORD_HEADER_LENGTH - 1, result.bytesConsumed());
        assertEquals(0, result.bytesProduced());
        remaining -= result.bytesConsumed();

        // We limit the buffer so we can read the header but not the rest, this should result in an
        // BUFFER_UNDERFLOW.
        encClientToServer.limit(SslUtils.SSL_RECORD_HEADER_LENGTH);
        result = server.unwrap(encClientToServer, plainServer);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertEquals(1, result.bytesConsumed());
        assertEquals(0, result.bytesProduced());
        remaining -= result.bytesConsumed();

        // We limit the buffer so we can read the header and partly the rest, this should result in an
        // BUFFER_UNDERFLOW.
        encClientToServer.limit(
                SslUtils.SSL_RECORD_HEADER_LENGTH  + remaining - 1 - SslUtils.SSL_RECORD_HEADER_LENGTH);
        result = server.unwrap(encClientToServer, plainServer);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertEquals(encClientToServer.limit() - SslUtils.SSL_RECORD_HEADER_LENGTH, result.bytesConsumed());
        assertEquals(0, result.bytesProduced());
        remaining -= result.bytesConsumed();

        // Reset limit so we can read the full record.
        encClientToServer.limit(remaining);
        assertEquals(0, encClientToServer.remaining());
        result = server.unwrap(encClientToServer, plainServer);
        assertEquals(SSLEngineResult.Status.BUFFER_UNDERFLOW, result.getStatus());
        assertEquals(0, result.bytesConsumed());
        assertEquals(0, result.bytesProduced());

        encClientToServer.position(0);
        result = server.unwrap(encClientToServer, plainServer);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertEquals(remaining, result.bytesConsumed());
        assertEquals(0, result.bytesProduced());
    } finally {
        cert.delete();
        cleanupClientSslEngine(client);
        cleanupServerSslEngine(server);
    }
}
 
源代码9 项目: Smack   文件: XmppTcpTransportModule.java
@Override
public OutputResult output(ByteBuffer outputData, boolean isFinalDataOfElement, boolean destinationAddressChanged,
        boolean moreDataAvailable) throws SSLException {
    if (outputData != null) {
        pendingOutputData.add(outputData);
        pendingOutputBytes += outputData.remaining();
        if (moreDataAvailable && pendingOutputBytes < MAX_PENDING_OUTPUT_BYTES) {
            return OutputResult.NO_OUTPUT;
        }
    }

    ByteBuffer[] outputDataArray = pendingOutputData.toArray(new ByteBuffer[pendingOutputData.size()]);

    myNetData.clear();

    while (true) {
        SSLEngineResult result;
        try {
            result = engine.wrap(outputDataArray, myNetData);
        } catch (SSLException e) {
            handleSslException(e);
            throw e;
        }

        debugLogSslEngineResult("wrap", result);

        SSLEngineResult.Status engineResultStatus = result.getStatus();

        pendingOutputBytes -= result.bytesConsumed();

        if (engineResultStatus == SSLEngineResult.Status.OK) {
            wrapInBytes += result.bytesConsumed();
            wrapOutBytes += result.bytesProduced();

            SSLEngineResult.HandshakeStatus handshakeStatus = handleHandshakeStatus(result);
            switch (handshakeStatus) {
                case NEED_UNWRAP:
                    // NEED_UNWRAP means that we need to receive something in order to continue the handshake. The
                    // standard channelSelectedCallback logic will take care of this, as there is eventually always
                    // a interest to read from the socket.
                    break;
                case NEED_WRAP:
                    // Same as need task: Cycle the reactor.
                case NEED_TASK:
                    // Note that we also set pendingOutputFilterData in the OutputResult in the NEED_TASK case, as
                    // we also want to retry the wrap() operation above in this case.
                    return new OutputResult(true, myNetData);
                default:
                    break;
            }
        }

        switch (engineResultStatus) {
        case OK:
            // No need to outputData.compact() here, since we do not reuse the buffer.
            // Clean up the pending output data.
            pruneBufferList(pendingOutputData);
            return new OutputResult(!pendingOutputData.isEmpty(), myNetData);
        case CLOSED:
            pendingOutputData.clear();
            return OutputResult.NO_OUTPUT;
        case BUFFER_OVERFLOW:
            LOGGER.warning("SSLEngine status BUFFER_OVERFLOW, this is hopefully uncommon");
            int outputDataRemaining = outputData != null ? outputData.remaining() : 0;
            int newCapacity = (int) (1.3 * outputDataRemaining);
            // If newCapacity would not increase myNetData, then double it.
            if (newCapacity <= myNetData.capacity()) {
                newCapacity = 2 * myNetData.capacity();
            }
            ByteBuffer newMyNetData = ByteBuffer.allocateDirect(newCapacity);
            myNetData.flip();
            newMyNetData.put(myNetData);
            myNetData = newMyNetData;
            continue;
        case BUFFER_UNDERFLOW:
            throw new IllegalStateException(
                    "Buffer underflow as result of SSLEngine.wrap() should never happen");
        }
    }
}
 
源代码10 项目: getty   文件: Worker.java
SSLEngineResult unwrap(ByteBuffer encryptedData) throws SSLException
{
  ByteBuffer allEncryptedData = _buffers.prependCached(encryptedData);
  _buffers.prepareForUnwrap(allEncryptedData);
  SSLEngineResult result = doUnwrap();
  debug("unwrap: doUnwrap result: " + result);
  allEncryptedData.position(result.bytesConsumed());
  ByteBuffer unprocessedEncryptedData = BufferUtils.slice(allEncryptedData);

  emitPlainData(result);

  switch (result.getStatus()) {
    case BUFFER_UNDERFLOW:
      _buffers.cache(unprocessedEncryptedData);
      break;
    case BUFFER_OVERFLOW:
      _buffers.grow(BufferType.IN_PLAIN);
      if (unprocessedEncryptedData == null) {
        throw new RuntimeException("Worker.unwrap had "
                + "buffer_overflow but all data was consumed!!");
      } else {
        unwrap(unprocessedEncryptedData);
      }
      break;
    case OK:
      if (unprocessedEncryptedData == null) {
        _buffers.clearCache();
      } else {
        _buffers.cache(unprocessedEncryptedData);
      }
      break;
    case CLOSED:

      break;
  }
  if (_buffers.isCacheEmpty() == false 
          && result.getStatus() == SSLEngineResult.Status.OK
          && result.bytesConsumed() > 0) {
    debug("Still data in cahce");
    result = unwrap(ByteBuffer.allocate(0));
  }
  return result;
}
 
源代码11 项目: mts   文件: SSLSocketChannel.java
public synchronized int write(ByteBuffer src) throws IOException
{
    if (socketChannel.socket().isOutputShutdown())
    {
        throw new ClosedChannelException();
    }
    else if (initialized != 0)
    {
        handshake(SelectionKey.OP_WRITE);
        return 0;
    }
    else if (shutdown)
    {
        shutdown();
        return 0;
    }

    // Check how much to write.
    int t = src.remaining();
    int n = 0;

    // Write as much as we can.
    SSLEngineResult result;
    Status status;
    do
    {
        if (!prepare(outputBuffer, minBufferSize))
        {
            // Overflow!
            break;
        }

        inputBuffer[0].flip();
        try
        {
            result = sslEngine.wrap(src, outputBuffer[0]);
        }
        finally
        {
            outputBuffer[0].flip();
        }
        n += result.bytesConsumed();
        status = result.getStatus();
        if (status == Status.OK)
        {
            if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK)
            {
                runTasks();
            }
        }
        else
        {
            if (status == Status.CLOSED)
            {
                shutdown();
            }

            throw new IOException("Write error '" + result.getStatus() + '\'');
        }
    } while (n < t);

    // Try to flush what we got.
    flush();

    return n;
}
 
源代码12 项目: sslfacade   文件: Worker.java
SSLEngineResult unwrap(ByteBuffer encryptedData) throws SSLException
{
  ByteBuffer allEncryptedData = _buffers.prependCached(encryptedData);
  _buffers.prepareForUnwrap(allEncryptedData);
  SSLEngineResult result = doUnwrap();
  debug("unwrap: doUnwrap result: " + result);
  allEncryptedData.position(result.bytesConsumed());
  ByteBuffer unprocessedEncryptedData = BufferUtils.slice(allEncryptedData);

  emitPlainData(result);

  switch (result.getStatus()) {
    case BUFFER_UNDERFLOW:
      _buffers.cache(unprocessedEncryptedData);
      break;
    case BUFFER_OVERFLOW:
      _buffers.grow(BufferType.IN_PLAIN);
      if (unprocessedEncryptedData == null) {
        throw new RuntimeException("Worker.unwrap had "
                + "buffer_overflow but all data was consumed!!");
      } else {
        unwrap(unprocessedEncryptedData);
      }
      break;
    case OK:
      if (unprocessedEncryptedData == null) {
        _buffers.clearCache();
      } else {
        _buffers.cache(unprocessedEncryptedData);
      }
      break;
    case CLOSED:

      break;
  }
  if (_buffers.isCacheEmpty() == false 
          && result.getStatus() == SSLEngineResult.Status.OK
          && result.bytesConsumed() > 0) {
    debug("Still data in cahce");
    result = unwrap(ByteBuffer.allocate(0));
  }
  return result;
}
 
源代码13 项目: IoTgo_Android_App   文件: SslConnection.java
private synchronized boolean unwrap(final Buffer buffer) throws IOException
{
    if (!_inbound.hasContent())
        return false;

    ByteBuffer bbuf=extractByteBuffer(buffer);
    final SSLEngineResult result;

    synchronized(bbuf)
    {
        ByteBuffer in_buffer=_inbound.getByteBuffer();
        synchronized(in_buffer)
        {
            try
            {
                bbuf.position(buffer.putIndex());
                bbuf.limit(buffer.capacity());
                in_buffer.position(_inbound.getIndex());
                in_buffer.limit(_inbound.putIndex());

                result=_engine.unwrap(in_buffer,bbuf);
                if (_logger.isDebugEnabled())
                    _logger.debug("{} unwrap {} {} consumed={} produced={}",
                        _session,
                        result.getStatus(),
                        result.getHandshakeStatus(),
                        result.bytesConsumed(),
                        result.bytesProduced());

                _inbound.skip(result.bytesConsumed());
                _inbound.compact();
                buffer.setPutIndex(buffer.putIndex()+result.bytesProduced());
            }
            catch(SSLException e)
            {
                _logger.debug(String.valueOf(_endp), e);
                _endp.close();
                throw e;
            }
            finally
            {
                in_buffer.position(0);
                in_buffer.limit(in_buffer.capacity());
                bbuf.position(0);
                bbuf.limit(bbuf.capacity());
            }
        }
    }

    switch(result.getStatus())
    {
        case BUFFER_UNDERFLOW:
            if (_endp.isInputShutdown())
                _inbound.clear();
            break;

        case BUFFER_OVERFLOW:
            if (_logger.isDebugEnabled()) _logger.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString());
            break;

        case OK:
            if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
                _handshook=true;
            break;

        case CLOSED:
            _logger.debug("unwrap CLOSE {} {}",this,result);
            if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
                _endp.close();
            break;

        default:
            _logger.debug("{} wrap default {}",_session,result);
        throw new IOException(result.toString());
    }

    //if (LOG.isDebugEnabled() && result.bytesProduced()>0)
    //    LOG.debug("{} unwrapped '{}'",_session,buffer);

    return result.bytesConsumed()>0 || result.bytesProduced()>0;
}
 
源代码14 项目: lams   文件: SslConduit.java
/**
 * Wraps the user data and attempts to send it to the remote client. If data has already been buffered then
 * this is attempted to be sent first.
 *
 * If the supplied buffers are null then a wrap operation is still attempted, which will happen during the
 * handshaking process.
 * @param userBuffers The buffers
 * @param off         The offset
 * @param len         The length
 * @return The amount of data consumed
 * @throws IOException
 */
private long doWrap(ByteBuffer[] userBuffers, int off, int len) throws IOException {
    if(anyAreSet(state, FLAG_CLOSED)) {
        throw new ClosedChannelException();
    }
    if(outstandingTasks > 0) {
        return 0;
    }
    if(anyAreSet(state, FLAG_WRITE_REQUIRES_READ)) {
        doUnwrap(null, 0, 0);
        if(allAreClear(state, FLAG_READ_REQUIRES_WRITE)) { //unless a wrap is immediatly required we just return
            return 0;
        }
    }
    if(wrappedData != null) {
        int res = sink.write(wrappedData.getBuffer());
        if(res == 0 || wrappedData.getBuffer().hasRemaining()) {
            return 0;
        }
        wrappedData.getBuffer().clear();
    } else {
        wrappedData = bufferPool.allocate();
    }
    try {
        SSLEngineResult result = null;
        while (result == null || (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP && result.getStatus() != SSLEngineResult.Status.BUFFER_OVERFLOW)) {
            if (userBuffers == null) {
                result = engine.wrap(EMPTY_BUFFER, wrappedData.getBuffer());
            } else {
                result = engine.wrap(userBuffers, off, len, wrappedData.getBuffer());
            }
        }
        wrappedData.getBuffer().flip();

        if (result.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
            throw new IOException("underflow"); //todo: can this happen?
        } else if (result.getStatus() == SSLEngineResult.Status.BUFFER_OVERFLOW) {
            if (!wrappedData.getBuffer().hasRemaining()) { //if an earlier wrap suceeded we ignore this
                throw new IOException("overflow"); //todo: handle properly
            }
        }
        //attempt to write it out, if we fail we just return
        //we ignore the handshake status, as wrap will get called again
        if (wrappedData.getBuffer().hasRemaining()) {
            sink.write(wrappedData.getBuffer());
        }
        //if it was not a complete write we just return
        if (wrappedData.getBuffer().hasRemaining()) {
            return result.bytesConsumed();
        }

        if (!handleHandshakeResult(result)) {
            return 0;
        }
        if (result.getStatus() == SSLEngineResult.Status.CLOSED && userBuffers != null) {
            notifyWriteClosed();
            throw new ClosedChannelException();
        }

        return result.bytesConsumed();
    } catch (RuntimeException|IOException|Error e) {
        try {
            close();
        } catch (Throwable ex) {
            UndertowLogger.REQUEST_LOGGER.debug("Exception closing SSLConduit after exception in doWrap()", ex);
        }
        throw e;
    } finally {
        //this can be cleared if the channel is fully closed
        if(wrappedData != null) {
            if (!wrappedData.getBuffer().hasRemaining()) {
                wrappedData.close();
                wrappedData = null;
            }
        }
    }
}
 
源代码15 项目: tomcatsrc   文件: AsyncChannelWrapperSecure.java
@Override
public void run() {
    long written = 0;

    try {
        for (int i = offset; i < offset + length; i++) {
            ByteBuffer src = srcs[i];
            while (src.hasRemaining()) {
                socketWriteBuffer.clear();

                // Encrypt the data
                SSLEngineResult r = sslEngine.wrap(src, socketWriteBuffer);
                written += r.bytesConsumed();
                Status s = r.getStatus();

                if (s == Status.OK || s == Status.BUFFER_OVERFLOW) {
                    // Need to write out the bytes and may need to read from
                    // the source again to empty it
                } else {
                    // Status.BUFFER_UNDERFLOW - only happens on unwrap
                    // Status.CLOSED - unexpected
                    throw new IllegalStateException(sm.getString(
                            "asyncChannelWrapperSecure.statusWrap"));
                }

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

                socketWriteBuffer.flip();

                // Do the write
                int toWrite = r.bytesProduced();
                while (toWrite > 0) {
                    Future<Integer> f =
                            socketChannel.write(socketWriteBuffer);
                    Integer socketWrite = f.get();
                    toWrite -= socketWrite.intValue();
                }
            }
        }


        if (writing.compareAndSet(true, false)) {
            future.complete(Long.valueOf(written));
        } else {
            future.fail(new IllegalStateException(sm.getString(
                    "asyncChannelWrapperSecure.wrongStateWrite")));
        }
    } catch (Exception e) {
        future.fail(e);
    }
}
 
源代码16 项目: ambry   文件: SSLTransmission.java
/**
 * Writes a sequence of bytes to this channel from the given buffer.
 *
 * @param src The buffer from which bytes are to be retrieved
 * @return The number of bytes decrypted and written to netWriteBuffer. No guarantee that data in the temporary
 * buffer will be completely written to the underlying channel right away. So the caller has to make sure to check
 * the remaining bytes in the netWriteBuffer apart from checking the remaining bytes in src bytebuffer. This method
 * is called from write() in the same class
 * @throws IOException If some other I/O error occurs
 */
@Override
public int write(ByteBuffer src) throws IOException {
  if (closing) {
    throw new IllegalStateException("Channel is in closing state");
  } else if (!handshakeComplete) {
    return 0;
  } else if (!flush(netWriteBuffer)) {
    return 0;
  }

  int written = 0;
  while (src.remaining() != 0) {
    netWriteBuffer.clear();
    long startTimeNs = SystemTime.getInstance().nanoseconds();
    SSLEngineResult wrapResult = sslEngine.wrap(src, netWriteBuffer);
    long encryptionTimeNs = SystemTime.getInstance().nanoseconds() - startTimeNs;
    logger.trace("SSL encryption time: {} ns for {} bytes", encryptionTimeNs, wrapResult.bytesConsumed());
    if (wrapResult.bytesConsumed() > 0) {
      metrics.sslEncryptionTimeInUsPerKB.mark(encryptionTimeNs / wrapResult.bytesConsumed());
    }
    netWriteBuffer.flip();
    //handle ssl renegotiation
    if (wrapResult.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING && wrapResult.getStatus() == Status.OK) {
      handshake();
      metrics.sslRenegotiationCount.inc();
      break;
    }

    if (wrapResult.getStatus() == SSLEngineResult.Status.OK) {
      written += wrapResult.bytesConsumed();
      if (!flush(netWriteBuffer)) {
        // break if socketChannel can't accept all data in netWriteBuffer
        break;
      }
      // otherwise, we are safe to clear the buffer for next iteration.
    } else if (wrapResult.getStatus() == Status.BUFFER_OVERFLOW) {
      handleWrapOverflow();
    } else if (wrapResult.getStatus() == Status.BUFFER_UNDERFLOW) {
      throw new IllegalStateException("SSL BUFFER_UNDERFLOW during write");
    } else if (wrapResult.getStatus() == Status.CLOSED) {
      throw new EOFException();
    }
  }
  return written;
}
 
源代码17 项目: qpid-proton-j   文件: SimpleSslTransportWrapper.java
/**
 * Wrap the underlying transport's output, passing it to the output buffer.
 *
 * {@link #_outputBuffer} is assumed to be writeable on entry and is guaranteed to
 * be still writeable on exit.
 */
private void wrapOutput() throws SSLException
{
    while (true) {
        int pending = _underlyingOutput.pending();
        if (pending < 0) {
            _head_closed = true;
        }

        ByteBuffer clearOutputBuffer = _underlyingOutput.head();
        SSLEngineResult result = _sslEngine.wrap(clearOutputBuffer, _outputBuffer);
        logEngineClientModeAndResult(result, "output");

        int written = result.bytesConsumed();
        _underlyingOutput.pop(written);
        pending = _underlyingOutput.pending();

        Status status = result.getStatus();
        switch (status) {
        case CLOSED:
            _head_closed = true;
            break;
        case OK:
            break;
        case BUFFER_OVERFLOW:
            ByteBuffer old = _outputBuffer;
            _outputBuffer = newWriteableBuffer(_outputBuffer.capacity()*2);
            _head = _outputBuffer.asReadOnlyBuffer();
            old.flip();
            _outputBuffer.put(old);
            continue;
        case BUFFER_UNDERFLOW:
            throw new IllegalStateException("app buffer underflow");
        }

        HandshakeStatus hstatus = result.getHandshakeStatus();
        switch (hstatus) {
        case NEED_UNWRAP:
            // wait for input data
            if (_inputBuffer.position() == 0 && _tail_closed) {
                _head_closed = true;
            }
            break;
        case NEED_WRAP:
            // keep looping
            continue;
        case NEED_TASK:
            runDelegatedTasks(result);
            continue;
        case FINISHED:
            updateCipherAndProtocolName(result);
            // intentionally fall through
        case NOT_HANDSHAKING:
            if (pending > 0 && status == Status.OK) {
                continue;
            } else {
                break;
            }
        }

        break;
    }
}
 
源代码18 项目: netty4.0.27Learn   文件: SslHandler.java
/**
 * 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();
        }
    }
}
 
源代码19 项目: IoTgo_Android_App   文件: SslConnection.java
private synchronized boolean wrap(final Buffer buffer) throws IOException
{
    ByteBuffer bbuf=extractByteBuffer(buffer);
    final SSLEngineResult result;

    synchronized(bbuf)
    {
        _outbound.compact();
        ByteBuffer out_buffer=_outbound.getByteBuffer();
        synchronized(out_buffer)
        {
            try
            {
                bbuf.position(buffer.getIndex());
                bbuf.limit(buffer.putIndex());
                out_buffer.position(_outbound.putIndex());
                out_buffer.limit(out_buffer.capacity());
                result=_engine.wrap(bbuf,out_buffer);
                if (_logger.isDebugEnabled())
                    _logger.debug("{} wrap {} {} consumed={} produced={}",
                        _session,
                        result.getStatus(),
                        result.getHandshakeStatus(),
                        result.bytesConsumed(),
                        result.bytesProduced());


                buffer.skip(result.bytesConsumed());
                _outbound.setPutIndex(_outbound.putIndex()+result.bytesProduced());
            }
            catch(SSLException e)
            {
                _logger.debug(String.valueOf(_endp), e);
                _endp.close();
                throw e;
            }
            finally
            {
                out_buffer.position(0);
                out_buffer.limit(out_buffer.capacity());
                bbuf.position(0);
                bbuf.limit(bbuf.capacity());
            }
        }
    }

    switch(result.getStatus())
    {
        case BUFFER_UNDERFLOW:
            throw new IllegalStateException();

        case BUFFER_OVERFLOW:
            break;

        case OK:
            if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
                _handshook=true;
            break;

        case CLOSED:
            _logger.debug("wrap CLOSE {} {}",this,result);
            if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
                _endp.close();
            break;

        default:
            _logger.debug("{} wrap default {}",_session,result);
        throw new IOException(result.toString());
    }

    return result.bytesConsumed()>0 || result.bytesProduced()>0;
}
 
源代码20 项目: IoTgo_Android_App   文件: SslConnection.java
private synchronized boolean unwrap(final Buffer buffer) throws IOException
{
    if (!_inbound.hasContent())
        return false;

    ByteBuffer bbuf=extractByteBuffer(buffer);
    final SSLEngineResult result;

    synchronized(bbuf)
    {
        ByteBuffer in_buffer=_inbound.getByteBuffer();
        synchronized(in_buffer)
        {
            try
            {
                bbuf.position(buffer.putIndex());
                bbuf.limit(buffer.capacity());
                in_buffer.position(_inbound.getIndex());
                in_buffer.limit(_inbound.putIndex());

                result=_engine.unwrap(in_buffer,bbuf);
                if (_logger.isDebugEnabled())
                    _logger.debug("{} unwrap {} {} consumed={} produced={}",
                        _session,
                        result.getStatus(),
                        result.getHandshakeStatus(),
                        result.bytesConsumed(),
                        result.bytesProduced());

                _inbound.skip(result.bytesConsumed());
                _inbound.compact();
                buffer.setPutIndex(buffer.putIndex()+result.bytesProduced());
            }
            catch(SSLException e)
            {
                _logger.debug(String.valueOf(_endp), e);
                _endp.close();
                throw e;
            }
            finally
            {
                in_buffer.position(0);
                in_buffer.limit(in_buffer.capacity());
                bbuf.position(0);
                bbuf.limit(bbuf.capacity());
            }
        }
    }

    switch(result.getStatus())
    {
        case BUFFER_UNDERFLOW:
            if (_endp.isInputShutdown())
                _inbound.clear();
            break;

        case BUFFER_OVERFLOW:
            if (_logger.isDebugEnabled()) _logger.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString());
            break;

        case OK:
            if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
                _handshook=true;
            break;

        case CLOSED:
            _logger.debug("unwrap CLOSE {} {}",this,result);
            if (result.getHandshakeStatus()==HandshakeStatus.FINISHED)
                _endp.close();
            break;

        default:
            _logger.debug("{} wrap default {}",_session,result);
        throw new IOException(result.toString());
    }

    //if (LOG.isDebugEnabled() && result.bytesProduced()>0)
    //    LOG.debug("{} unwrapped '{}'",_session,buffer);

    return result.bytesConsumed()>0 || result.bytesProduced()>0;
}