Java Code Examples for javax.net.ssl.SSLEngineResult#getHandshakeStatus()

The following examples show how to use javax.net.ssl.SSLEngineResult#getHandshakeStatus() . 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: SSLSocket.java    From whiskey with Apache License 2.0 6 votes vote down vote up
private void wrap() throws IOException {

            ArrayList<ByteBuffer> wrapped = new ArrayList<>();

            while (true) {
                // TODO(bgallagher) buffer pooling
                ByteBuffer out = ByteBuffer.allocate(engine.getSession().getPacketBufferSize());

                SSLEngineResult result = engine.wrap(pending(), out);

                if (result.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
                    throw new SSLException("renegotiation not supported");
                }

                if (result.bytesProduced() > 0) {
                    out.flip();
                    wrapped.add(out);
                } else {
                    break;
                }
            }

            setPending(wrapped.toArray(new ByteBuffer[wrapped.size()]));
        }
 
Example 2
Source File: SecureNio2Channel.java    From Tomcat8-Source-Read with MIT License 6 votes vote down vote up
/**
 * Perform handshake unwrap
 * @return the result
 * @throws IOException An IO error occurred
 */
protected SSLEngineResult handshakeUnwrap() throws IOException {
    SSLEngineResult result;
    boolean cont = false;
    //loop while we can perform pure SSLEngine data
    do {
        //prepare the buffer with the incoming data
        netInBuffer.flip();
        //call unwrap
        getBufHandler().configureReadBufferForWrite();
        result = sslEngine.unwrap(netInBuffer, getBufHandler().getReadBuffer());
        //compact the buffer, this is an optional method, wonder what would happen if we didn't
        netInBuffer.compact();
        //read in the status
        handshakeStatus = result.getHandshakeStatus();
        if (result.getStatus() == SSLEngineResult.Status.OK &&
             result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
            //execute tasks if we need to
            handshakeStatus = tasks();
        }
        //perform another unwrap?
        cont = result.getStatus() == SSLEngineResult.Status.OK &&
               handshakeStatus == HandshakeStatus.NEED_UNWRAP;
    } while (cont);
    return result;
}
 
Example 3
Source File: SSLEngineTest.java    From netty-4.1.22 with Apache License 2.0 6 votes vote down vote up
private void testBeginHandshakeCloseOutbound(SSLEngine engine) throws SSLException {
    ByteBuffer dst = allocateBuffer(engine.getSession().getPacketBufferSize());
    ByteBuffer empty = allocateBuffer(0);
    engine.beginHandshake();
    engine.closeOutbound();

    SSLEngineResult result;
    for (;;) {
        result = engine.wrap(empty, dst);
        dst.flip();

        assertEquals(0, result.bytesConsumed());
        assertEquals(dst.remaining(), result.bytesProduced());
        if (result.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NEED_WRAP) {
            break;
        }
        dst.clear();
    }
    assertEquals(SSLEngineResult.Status.CLOSED, result.getStatus());
}
 
Example 4
Source File: BlockingSslHandler.java    From ignite with Apache License 2.0 6 votes vote down vote up
/**
 * Does post-handshake logic described <a href="https://tools.ietf.org/html/rfc8446#section-4.6">here</a> if nedded.
 *
 * @param res Response.
 */
private SSLEngineResult postHandshakeIfNeded(SSLEngineResult res) throws SSLException, IgniteCheckedException {
    while (res.getHandshakeStatus() == FINISHED && res.getStatus() == OK) {
        if (!inNetBuf.hasRemaining()) {
            inNetBuf.clear();

            readFromNet();

            inNetBuf.flip();
        }

        res = unwrap0();

        handshakeStatus = res.getHandshakeStatus();

        if (log.isDebugEnabled())
            log.debug("Unrapped post-handshake data [status=" + res.getStatus() + ", handshakeStatus=" +
                handshakeStatus + ']');
    }

    return res;
}
 
Example 5
Source File: TlsCryptoSocket.java    From vespa with Apache License 2.0 5 votes vote down vote up
private int applicationDataWrap(ByteBuffer src) throws IOException {
    SSLEngineResult result = sslEngineWrap(src);
    if (result.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING) throw new SSLException("Renegotiation detected");
    switch (result.getStatus()) {
        case OK:
            return result.bytesConsumed();
        case BUFFER_OVERFLOW:
            return 0;
        default:
            throw unexpectedStatusException(result.getStatus());
    }
}
 
Example 6
Source File: SSLSocket.java    From whiskey with Apache License 2.0 5 votes vote down vote up
@Override
boolean doRead(SocketChannel channel) throws IOException {

    ByteBuffer out = getBuffer();

    int bytesRead = channel.read(bufferedWrapped);

    if (bytesRead < 0) {
        fail(new IOException("connection closed"));
        return true;
    }

    bufferedWrapped.flip();

    SSLEngineResult.Status status = SSLEngineResult.Status.OK;
    while (out.remaining() > 0 && bufferedWrapped.remaining() > 0 && status ==
        SSLEngineResult.Status.OK) {

        SSLEngineResult result = engine.unwrap(bufferedWrapped, out);
        status = result.getStatus();

        if (result.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
            throw new SSLException("renegotiation not supported");
        }

    }

    bufferedWrapped.compact();

    out.flip();
    set(out);
    return true;
}
 
Example 7
Source File: SSLSocketChannel.java    From mts with GNU General Public License v3.0 5 votes vote down vote up
public synchronized boolean shutdown() throws IOException
{
    shutdown = true;

    if (!sslEngine.isOutboundDone())
    {
        sslEngine.closeOutbound();
    }

    // Try to "fire-and-forget" the closed notification (RFC2616).
    SSLEngineResult result;
    if (prepare(outputBuffer, minBufferSize))
    {
        result = sslEngine.wrap(emptyBuffer, outputBuffer[0]);
        if (result.getStatus() != Status.CLOSED)
        {
            throw new SSLException("Unexpected shutdown status '" + result.getStatus() + '\'');
        }
        outputBuffer[0].flip();
    }
    else
    {
        result = null;
    }
    flush(outputBuffer[0]);
    return !outputBuffer[0].hasRemaining() && (result != null)
        && (result.getHandshakeStatus() != HandshakeStatus.NEED_WRAP);
}
 
Example 8
Source File: SimpleSslTransportWrapper.java    From qpid-proton-j with Apache License 2.0 5 votes vote down vote up
private void updateCipherAndProtocolName(SSLEngineResult result)
{
    if (result.getHandshakeStatus() == HandshakeStatus.FINISHED)
    {
        _cipherName = _sslEngine.getCipherSuite();
        _protocolName = _sslEngine.getProtocol();
    }
}
 
Example 9
Source File: SslConduit.java    From lams with GNU General Public License v2.0 5 votes vote down vote up
private boolean handleHandshakeResult(SSLEngineResult result) throws IOException {
    switch (result.getHandshakeStatus()) {
        case NEED_TASK: {
            state |= FLAG_IN_HANDSHAKE;
            clearReadRequiresWrite();
            clearWriteRequiresRead();
            runTasks();
            return false;
        }
        case NEED_UNWRAP: {
            clearReadRequiresWrite();
            state |= FLAG_WRITE_REQUIRES_READ | FLAG_IN_HANDSHAKE;
            sink.suspendWrites();
            if(anyAreSet(state, FLAG_WRITES_RESUMED)) {
                source.resumeReads();
            }

            return false;
        }
        case NEED_WRAP: {
            clearWriteRequiresRead();
            state |= FLAG_READ_REQUIRES_WRITE | FLAG_IN_HANDSHAKE;
            source.suspendReads();
            if(anyAreSet(state, FLAG_READS_RESUMED)) {
                sink.resumeWrites();
            }
            return false;
        }
        case FINISHED: {
            if(anyAreSet(state, FLAG_IN_HANDSHAKE)) {
                state &= ~FLAG_IN_HANDSHAKE;
                handshakeCallback.run();
            }
        }
    }
    clearReadRequiresWrite();
    clearWriteRequiresRead();
    return true;
}
 
Example 10
Source File: TestTLS12.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
private static void runDelegatedTasks(SSLEngineResult result,
        SSLEngine engine) throws Exception {

    if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
        Runnable runnable;
        while ((runnable = engine.getDelegatedTask()) != null) {
            runnable.run();
        }
        HandshakeStatus hsStatus = engine.getHandshakeStatus();
        if (hsStatus == HandshakeStatus.NEED_TASK) {
            throw new Exception(
                "handshake shouldn't need additional tasks");
        }
    }
}
 
Example 11
Source File: AbstractSslEngineBenchmark.java    From netty-4.1.22 with Apache License 2.0 5 votes vote down vote up
private static void runDelegatedTasks(SSLEngineResult result, SSLEngine engine) {
    if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
        for (;;) {
            Runnable task = engine.getDelegatedTask();
            if (task == null) {
                break;
            }
            task.run();
        }
    }
}
 
Example 12
Source File: SSLSocket.java    From whiskey with Apache License 2.0 5 votes vote down vote up
private void wrapHandshake() throws IOException {
    ByteBuffer out = ByteBuffer.allocate(engine.getSession().getPacketBufferSize());

    SSLEngineResult result;
    do {
        result = engine.wrap(EMPTY_BUFFER_ARRAY, out);

        if (result.bytesProduced() > 0) {
            out.flip();
            handshakeWriteQueue.add(new WriteFuture(new ByteBuffer[] { out }));
            out = ByteBuffer.allocate(engine.getSession().getPacketBufferSize());
        }

        switch (result.getHandshakeStatus()) {
            case FINISHED:
                super.finishConnect();
                break;
            case NEED_TASK:
                runDelegatedTasks(engine);
                break;
            case NEED_UNWRAP:
                readAndUnwrapHandshake();
                break;
            case NEED_WRAP:
            case NOT_HANDSHAKING:
                break;
        }
    } while (result.bytesProduced() > 0);
}
 
Example 13
Source File: SslConnection.java    From WebSocket-for-Android with Apache License 2.0 4 votes vote down vote up
@SuppressLint("TrulyRandom")
private synchronized boolean wrap(final Buffer buffer) throws IOException
{
    ByteBuffer bbuf=extractByteBuffer(buffer);
    final SSLEngineResult result;
    int encrypted_produced = 0;
    int decrypted_consumed = 0;
    synchronized(bbuf)
    {
        _outbound.compact();
        ByteBuffer out_buffer=_outbound.getByteBuffer();
        synchronized(out_buffer)
        {
            try
            {
                bbuf.position(buffer.getIndex());
                bbuf.limit(buffer.putIndex());
                int decrypted_position = bbuf.position();

                out_buffer.position(_outbound.putIndex());
                out_buffer.limit(out_buffer.capacity());
                int encrypted_position = out_buffer.position();

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

                decrypted_consumed = bbuf.position() - decrypted_position;
                buffer.skip(decrypted_consumed);

                encrypted_produced = out_buffer.position() - encrypted_position;
                _outbound.setPutIndex(_outbound.putIndex() + encrypted_produced);
            }
            catch(SSLException e)
            {
                _logger.debug(String.valueOf(_endp), e);
                _endp.close();
                throw e;
            }
            catch (Exception x)
            {
                throw new IOException(x);
            }
            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 decrypted_consumed > 0 || encrypted_produced > 0;
}
 
Example 14
Source File: Worker.java    From sslfacade with MIT License 4 votes vote down vote up
void handleEnOfSession(final SSLEngineResult result)
{
  if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
    _sessionClosedListener.onSessionClosed();
  }
}
 
Example 15
Source File: SslHandler.java    From jane with GNU Lesser General Public License v3.0 4 votes vote down vote up
/**
 * Perform any handshaking processing.
 */
void handshake(NextFilter nextFilter) throws Exception {
	for (;;) {
		switch (handshakeStatus) {
		case FINISHED:
			// LOGGER.debug("{} processing the FINISHED state", SslFilter.getSessionInfo(session));

			handshakeComplete = true;

			// Send the SECURE message only if it's the first SSL handshake
			if (firstSSLNegociation) {
				firstSSLNegociation = false;
				if (session.containsAttribute(SslFilter.USE_NOTIFICATION))
					scheduleMessageReceived(nextFilter, SslFilter.SESSION_SECURED);
			}

			// if (!isOutboundDone()) {
			// 	LOGGER.debug("{} is now secured", SslFilter.getSessionInfo(session));
			// } else {
			// 	LOGGER.debug("{} is not secured yet", SslFilter.getSessionInfo(session));
			// }

			return;
		case NEED_TASK:
			// LOGGER.debug("{} processing the NEED_TASK state", SslFilter.getSessionInfo(session));

			handshakeStatus = doTasks();
			break;
		case NEED_UNWRAP:
			// LOGGER.debug("{} processing the NEED_UNWRAP state", SslFilter.getSessionInfo(session));

			// we need more data read
			if (unwrapHandshake(nextFilter) == Status.BUFFER_UNDERFLOW && handshakeStatus != HandshakeStatus.FINISHED || isInboundDone())
				return; // We need more data or the session is closed

			break;
		case NEED_WRAP:
		case NOT_HANDSHAKING:
			// LOGGER.debug("{} processing the NEED_WRAP state", SslFilter.getSessionInfo(session));

			// First make sure that the out buffer is completely empty.
			// Since we cannot call wrap with data left on the buffer
			if (outNetBuffer != null && outNetBuffer.hasRemaining())
				return;

			createOutNetBuffer(0);

			for (;;) { //NOSONAR
				SSLEngineResult result = sslEngine.wrap(SimpleBufferAllocator.emptyBuffer.buf(), outNetBuffer.buf());
				if (result.getStatus() != Status.BUFFER_OVERFLOW) {
					handshakeStatus = result.getHandshakeStatus();
					break;
				}
				outNetBuffer = IoBuffer.reallocate(outNetBuffer, outNetBuffer.capacity() << 1);
				outNetBuffer.limit(outNetBuffer.capacity());
			}

			outNetBuffer.flip();
			writeNetBuffer(nextFilter, false);
			break;
		default:
			String msg = "invalid handshaking state" + handshakeStatus + " while processing the handshake for session " + session.getId();
			ExceptionMonitor.getInstance().error(msg);
			throw new IllegalStateException(msg);
		}
	}
}
 
Example 16
Source File: SSLSocketChannel.java    From mts with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Handshake wrap.
 * 
 * @param ops the current ready operations set.
 * @return the interest set to continue or 0 if finished.
 * @throws IOException on I/O errors.
 */
private synchronized int wrap(int ops) throws IOException
{
    // Prepare the buffer.
    if (prepare(outputBuffer, minBufferSize))
    {
        // Wrap the buffer.
        SSLEngineResult result;
        Status status;
        try
        {
            result = sslEngine.wrap(emptyBuffer, outputBuffer[0]);
        }
        finally
        {
            outputBuffer[0].flip();
        }
        handshake = result.getHandshakeStatus();

        status = result.getStatus();
        if (status == Status.OK)
        {
            if (handshake == HandshakeStatus.NEED_TASK)
            {
                handshake = runTasks();
            }
        }
        else
        {
            // BUFFER_OVERFLOW/BUFFER_UNDERFLOW/CLOSED
            throw new IOException("Handshake failed '" + status + '\'');
        }
    }

    // Flush the buffer, if applicable.
    if ((ops & SelectionKey.OP_WRITE) != 0)
    {
        flush(outputBuffer[0]);
    }

    return outputBuffer[0].hasRemaining() ? SelectionKey.OP_WRITE : 0;
}
 
Example 17
Source File: TlsHelper.java    From an2linuxclient with GNU General Public License v3.0 4 votes vote down vote up
public static SSLEngineResult.HandshakeStatus doHandshake(SSLEngine tlsEngine,
                                                          ByteBuffer netDataBuf,
                                                          OutputStream out,
                                                          InputStream in){
    try {
        ByteBuffer empty;
        /*Apparently on Android 4.4 (API_19) SSLEngine whines about BUFFER_OVERFLOW for this
        buffer even though nothing ever gets written to it*/
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH){
            empty = ByteBuffer.allocate(0);
        } else {
            empty = ByteBuffer.allocate(tlsEngine.getSession().getApplicationBufferSize());
        }

        // ClientHello -> netDataBuf
        tlsEngine.wrap(empty, netDataBuf);
        netDataBuf.flip();
        byte[] clientHello = new byte[netDataBuf.limit()];
        netDataBuf.get(clientHello);
        out.write(ConnectionHelper.intToByteArray(clientHello.length));
        out.write(clientHello);

        // netDataBuf <- ServerHello..ServerHelloDone
        int serverHelloSize = ByteBuffer.wrap(ConnectionHelper.readAll(4, in)).getInt();
        byte[] serverHello = ConnectionHelper.readAll(serverHelloSize, in);
        netDataBuf.clear();
        netDataBuf.put(serverHello);
        netDataBuf.flip();
        SSLEngineResult result = tlsEngine.unwrap(netDataBuf, empty);
        while (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP){
            result = tlsEngine.unwrap(netDataBuf, empty);
        }
        Runnable task = tlsEngine.getDelegatedTask();
        while (task != null){
            task.run();
            task = tlsEngine.getDelegatedTask();
        }

        // [client]Certificate*..ClientKeyExchange..Finished -> netDataBuf
        netDataBuf.clear();
        result = tlsEngine.wrap(empty, netDataBuf);
        while (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP){
            result = tlsEngine.wrap(empty, netDataBuf);
        }
        netDataBuf.flip();
        byte[] clientKeyExchange = new byte[netDataBuf.limit()];
        netDataBuf.get(clientKeyExchange);
        out.write(ConnectionHelper.intToByteArray(clientKeyExchange.length));
        out.write(clientKeyExchange);

        // netDataBuf <- ChangeCipherSpec..Finished
        int serverChangeCipherSpecSize = ByteBuffer.wrap(ConnectionHelper.readAll(4, in)).getInt();
        byte[] serverChangeCipherSpec = ConnectionHelper.readAll(serverChangeCipherSpecSize, in);
        netDataBuf.clear();
        netDataBuf.put(serverChangeCipherSpec);
        netDataBuf.flip();
        result = tlsEngine.unwrap(netDataBuf, empty);
        while (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP){
            result = tlsEngine.unwrap(netDataBuf, empty);
        }

        /*On Android 8.1 (LineageOS 15.1) on a Xiaomi device (not sure about others) the
        SSL_ENGINE may return NEED_WRAP here, so we do that even though no data gets written
        by the SSL_ENGINE ???*/
        if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
            netDataBuf.clear();
            result = tlsEngine.wrap(empty, netDataBuf);
            // netDataBuf still empty here...
        }

        /*Apparently on Android 4.4 (API_19) with SSLEngine the latest call tlsEngine.unwrap(..)
        that finishes the handshake returns NOT_HANDSHAKING instead of FINISHED as the result*/
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH){
            return result.getHandshakeStatus();
        } else {
            if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING){
                return SSLEngineResult.HandshakeStatus.FINISHED;
            } else if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED) {
                // just in case
                return result.getHandshakeStatus();
            } else {
                return null;
            }
        }
    } catch (IOException e){
        return null;
    }
}
 
Example 18
Source File: SslHandler.java    From neoscada with Eclipse Public License 1.0 4 votes vote down vote up
private SSLEngineResult.Status unwrapHandshake(NextFilter nextFilter) throws SSLException {
    // Prepare the net data for reading.
    if (inNetBuffer != null) {
        inNetBuffer.flip();
    }

    if (inNetBuffer == null || !inNetBuffer.hasRemaining()) {
        // Need more data.
        return SSLEngineResult.Status.BUFFER_UNDERFLOW;
    }

    SSLEngineResult res = unwrap();
    handshakeStatus = res.getHandshakeStatus();

    checkStatus(res);

    // If handshake finished, no data was produced, and the status is still
    // ok, try to unwrap more
    if (handshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED && res.getStatus() == SSLEngineResult.Status.OK
            && inNetBuffer.hasRemaining()) {
        res = unwrap();

        // prepare to be written again
        if (inNetBuffer.hasRemaining()) {
            inNetBuffer.compact();
        } else {
            inNetBuffer = null;
        }

        renegotiateIfNeeded(nextFilter, res);
    } else {
        // prepare to be written again
        if (inNetBuffer.hasRemaining()) {
            inNetBuffer.compact();
        } else {
            inNetBuffer = null;
        }
    }

    return res.getStatus();
}
 
Example 19
Source File: ExportControlled.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Perform the handshaking step of the TLS connection. We use the `sslEngine' along with the `channel' to exchange messages with the server to setup an
 * encrypted channel.
 * 
 * @param sslEngine
 *            {@link SSLEngine}
 * @param channel
 *            {@link AsynchronousSocketChannel}
 * @throws SSLException
 *             in case of handshake error
 */
private static void performTlsHandshake(SSLEngine sslEngine, AsynchronousSocketChannel channel) throws SSLException {
    sslEngine.beginHandshake();
    HandshakeStatus handshakeStatus = sslEngine.getHandshakeStatus();

    // Create byte buffers to use for holding application data
    int packetBufferSize = sslEngine.getSession().getPacketBufferSize();
    ByteBuffer myNetData = ByteBuffer.allocate(packetBufferSize);
    ByteBuffer peerNetData = ByteBuffer.allocate(packetBufferSize);
    int appBufferSize = sslEngine.getSession().getApplicationBufferSize();
    ByteBuffer myAppData = ByteBuffer.allocate(appBufferSize);
    ByteBuffer peerAppData = ByteBuffer.allocate(appBufferSize);

    SSLEngineResult res = null;

    while (handshakeStatus != HandshakeStatus.FINISHED && handshakeStatus != HandshakeStatus.NOT_HANDSHAKING) {
        switch (handshakeStatus) {
            case NEED_WRAP:
                myNetData.clear();
                res = sslEngine.wrap(myAppData, myNetData);
                handshakeStatus = res.getHandshakeStatus();
                switch (res.getStatus()) {
                    case OK:
                        myNetData.flip();
                        write(channel, myNetData);
                        break;
                    case BUFFER_OVERFLOW:
                    case BUFFER_UNDERFLOW:
                    case CLOSED:
                        throw new CJCommunicationsException("Unacceptable SSLEngine result: " + res);
                }
                break;
            case NEED_UNWRAP:
                peerNetData.flip(); // Process incoming handshaking data
                res = sslEngine.unwrap(peerNetData, peerAppData);
                handshakeStatus = res.getHandshakeStatus();
                switch (res.getStatus()) {
                    case OK:
                        peerNetData.compact();
                        break;
                    case BUFFER_OVERFLOW:
                        // Check if we need to enlarge the peer application data buffer.
                        final int newPeerAppDataSize = sslEngine.getSession().getApplicationBufferSize();
                        if (newPeerAppDataSize > peerAppData.capacity()) {
                            // enlarge the peer application data buffer
                            ByteBuffer newPeerAppData = ByteBuffer.allocate(newPeerAppDataSize);
                            newPeerAppData.put(peerAppData);
                            newPeerAppData.flip();
                            peerAppData = newPeerAppData;
                        } else {
                            peerAppData.compact();
                        }
                        break;
                    case BUFFER_UNDERFLOW:
                        // Check if we need to enlarge the peer network packet buffer
                        final int newPeerNetDataSize = sslEngine.getSession().getPacketBufferSize();
                        if (newPeerNetDataSize > peerNetData.capacity()) {
                            // enlarge the peer network packet buffer
                            ByteBuffer newPeerNetData = ByteBuffer.allocate(newPeerNetDataSize);
                            newPeerNetData.put(peerNetData);
                            newPeerNetData.flip();
                            peerNetData = newPeerNetData;
                        } else {
                            peerNetData.compact();
                        }
                        // obtain more inbound network data and then retry the operation
                        if (read(channel, peerNetData) < 0) {
                            throw new CJCommunicationsException("Server does not provide enough data to proceed with SSL handshake.");
                        }
                        break;
                    case CLOSED:
                        throw new CJCommunicationsException("Unacceptable SSLEngine result: " + res);
                }
                break;

            case NEED_TASK:
                sslEngine.getDelegatedTask().run();
                handshakeStatus = sslEngine.getHandshakeStatus();
                break;
            case FINISHED:
            case NOT_HANDSHAKING:
                break;
        }
    }
}
 
Example 20
Source File: SSLSocketChannel.java    From mts with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Handshake unwrap.
 * 
 * @param ops the current ready operations set.
 * @return the interest set to continue or 0 if finished.
 * @throws IOException on I/O errors.
 */
private synchronized int unwrap(int ops) throws IOException
{
    // Fill the buffer, if applicable.
    if ((ops & SelectionKey.OP_READ) != 0)
    {
        fill(inputBuffer[0]);
    }

    // Unwrap the buffer.
    SSLEngineResult result;
    Status status;
    do
    {
        // Prepare the input cache, although no app
        // data should be produced during handshake.
        prepare(inputCache, minCacheSize);
        inputBuffer[0].flip();
        try
        {
            result = sslEngine.unwrap(inputBuffer[0], inputCache[0]);
        }
        finally
        {
            inputBuffer[0].compact();
            inputCache[0].flip();
        }
        handshake = result.getHandshakeStatus();

        status = result.getStatus();
        if (status == Status.OK)
        {
            if (handshake == HandshakeStatus.NEED_TASK)
            {
                handshake = runTasks();
            }
        }
        else if (status == Status.BUFFER_UNDERFLOW)
        {
            return SelectionKey.OP_READ;
        }
        else
        {
            // BUFFER_OVERFLOW/CLOSED
            throw new IOException("Handshake failed '" + status + '\'');
        }
    } while (handshake == HandshakeStatus.NEED_UNWRAP);

    return 0;
}