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

The following examples show how to use javax.net.ssl.SSLEngine#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: SSLSocketChannel2.java    From ans-android-sdk with GNU General Public License v3.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 2
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 3
Source File: SSLSocketChannel2.java    From clevertap-android-sdk 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 4
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 5
Source File: TestTLS12.java    From dragonwell8_jdk 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 6
Source File: TestTLS12.java    From TencentKona-8 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 7
Source File: SSLCodec.java    From NetBare with MIT License 5 votes vote down vote up
void handshake(SSLEngine engine, ByteBuffer input, CodecCallback callback)
        throws IOException {
    if (!mHandshakeStarted) {
        engine.beginHandshake();
        mHandshakeStarted = true;
    }
    SSLEngineResult.HandshakeStatus status = engine.getHandshakeStatus();
    while (!mHandshakeFinished) {
        if (mEngineClosed) {
            throw new IOException("Handshake failed: Engine is closed.");
        }
        if (status == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
            // Should never happen
            throw new IOException("Handshake failed: Invalid handshake status: " + status);
        } else if (status == SSLEngineResult.HandshakeStatus.FINISHED) {
            mHandshakeFinished = true;
            NetBareLog.i("SSL handshake finished!");
            if (input.hasRemaining()) {
                decode(engine, input, callback);
            }
        } else if (status == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
            status = handshakeWrap(engine, callback).getHandshakeStatus();
        } else if (status == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
            // Wait next encrypted buffer.
            if (!input.hasRemaining()) {
                break;
            }
            status = handshakeUnwrap(engine, input, callback).getHandshakeStatus();
        } else if (status == SSLEngineResult.HandshakeStatus.NEED_TASK) {
            runDelegatedTasks(engine);
        }
    }
}
 
Example 8
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 9
Source File: DiameterFirewall.java    From SigFW with GNU Affero General Public License v3.0 5 votes vote down vote up
/**
 * DTLS retransmission if timeout
 */
boolean dtls_onReceiveTimeout(SSLEngine engine, /*SocketAddress socketAddr,*/ String peer_realm, 
        String side, List<DatagramOverDiameterPacket> packets) throws Exception {

    SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
    if (hs == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
        return false;
    } else {
        // retransmission of handshake messages
        return dtls_produceHandshakePackets(engine, peer_realm, side, packets);
    }
}
 
Example 10
Source File: DiameterFirewall.java    From SigFW with GNU Affero General Public License v3.0 5 votes vote down vote up
/**
 * DTLS run delegated tasks
 */
void dtls_runDelegatedTasks(SSLEngine engine) throws Exception {
    Runnable runnable;
    while ((runnable = engine.getDelegatedTask()) != null) {
        runnable.run();
    }

    SSLEngineResult.HandshakeStatus hs = engine.getHandshakeStatus();
    if (hs == SSLEngineResult.HandshakeStatus.NEED_TASK) {
        throw new Exception("handshake shouldn't need additional tasks");
    }
}
 
Example 11
Source File: SSLEngineTestCase.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
private static void runDelegatedTasks(SSLEngine engine) {
    Runnable runnable;
    System.out.println("Running delegated tasks...");
    while ((runnable = engine.getDelegatedTask()) != null) {
        runnable.run();
    }
    HandshakeStatus hs = engine.getHandshakeStatus();
    if (hs == HandshakeStatus.NEED_TASK) {
        throw new Error("Handshake shouldn't need additional tasks.");
    }
}
 
Example 12
Source File: TestTLS12.java    From jdk8u_jdk 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 13
Source File: BlockingSslHandler.java    From ignite with Apache License 2.0 5 votes vote down vote up
/**
 * @param sslEngine SSLEngine.
 * @param ch Socket channel.
 * @param directBuf Direct buffer flag.
 * @param order Byte order.
 * @param log Logger.
 */
public BlockingSslHandler(SSLEngine sslEngine,
    SocketChannel ch,
    boolean directBuf,
    ByteOrder order,
    IgniteLogger log)
    throws SSLException {
    this.ch = ch;
    this.log = log;
    this.sslEngine = sslEngine;
    this.order = order;

    // Allocate a little bit more so SSL engine would not return buffer overflow status.
    //
    // System property override is for test purposes only.
    int netBufSize = Integer.getInteger("BlockingSslHandler.netBufSize",
        sslEngine.getSession().getPacketBufferSize() + 50);

    outNetBuf = directBuf ? ByteBuffer.allocateDirect(netBufSize) : ByteBuffer.allocate(netBufSize);
    outNetBuf.order(order);

    // Initially buffer is empty.
    outNetBuf.position(0);
    outNetBuf.limit(0);

    inNetBuf = directBuf ? ByteBuffer.allocateDirect(netBufSize) : ByteBuffer.allocate(netBufSize);
    inNetBuf.order(order);

    appBuf = allocateAppBuff();

    handshakeStatus = sslEngine.getHandshakeStatus();

    if (log.isDebugEnabled())
        log.debug("Started SSL session [netBufSize=" + netBufSize + ", appBufSize=" + appBuf.capacity() + ']');
}
 
Example 14
Source File: Link.java    From cloudstack with Apache License 2.0 4 votes vote down vote up
public static boolean doHandshake(final SocketChannel socketChannel, final SSLEngine sslEngine) throws IOException {
    if (socketChannel == null || sslEngine == null) {
        return false;
    }
    final int appBufferSize = sslEngine.getSession().getApplicationBufferSize();
    final int netBufferSize = sslEngine.getSession().getPacketBufferSize();
    ByteBuffer myAppData = ByteBuffer.allocate(appBufferSize);
    ByteBuffer peerAppData = ByteBuffer.allocate(appBufferSize);
    ByteBuffer myNetData = ByteBuffer.allocate(netBufferSize);
    ByteBuffer peerNetData = ByteBuffer.allocate(netBufferSize);

    final Executor executor = Executors.newSingleThreadExecutor();
    final long startTimeMills = System.currentTimeMillis();

    HandshakeStatus handshakeStatus = sslEngine.getHandshakeStatus();
    while (handshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED
            && handshakeStatus != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
        final long timeTaken = System.currentTimeMillis() - startTimeMills;
        if (timeTaken > 30000L) {
            s_logger.warn("SSL Handshake has taken more than 30s to connect to: " + socketChannel.getRemoteAddress() +
                    ". Please investigate this connection.");
            return false;
        }
        switch (handshakeStatus) {
            case NEED_UNWRAP:
                final HandshakeHolder unwrapResult = doHandshakeUnwrap(socketChannel, sslEngine, peerAppData, peerNetData, appBufferSize);
                peerAppData = unwrapResult.getAppDataBuffer();
                peerNetData = unwrapResult.getNetDataBuffer();
                if (!unwrapResult.isSuccess()) {
                    return false;
                }
                break;
            case NEED_WRAP:
                final HandshakeHolder wrapResult = doHandshakeWrap(socketChannel, sslEngine,  myAppData, myNetData, peerNetData, netBufferSize);
                myNetData = wrapResult.getNetDataBuffer();
                if (!wrapResult.isSuccess()) {
                    return false;
                }
                break;
            case NEED_TASK:
                Runnable task;
                while ((task = sslEngine.getDelegatedTask()) != null) {
                    if (s_logger.isTraceEnabled()) {
                        s_logger.trace("SSL: Running delegated task!");
                    }
                    executor.execute(task);
                }
                break;
            case FINISHED:
                break;
            case NOT_HANDSHAKING:
                break;
            default:
                throw new IllegalStateException("Invalid SSL status: " + handshakeStatus);
        }
        handshakeStatus = sslEngine.getHandshakeStatus();
    }
    return true;
}
 
Example 15
Source File: ExportControlled.java    From FoxTelem with GNU General Public License v3.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 16
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 17
Source File: DiameterFirewall.java    From SigFW with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * DTLS produce handshake packets
 */
boolean dtls_produceHandshakePackets(SSLEngine engine, /*SocketAddress socketAddr,*/ String peer_realm,
        String side, List<DatagramOverDiameterPacket> packets) throws Exception {

    long _t = System.currentTimeMillis();
    long _end = _t + DTLS_MAX_HANDSHAKE_DURATION*1000;

    boolean endLoops = false;
    int loops = DTLS_MAX_HANDSHAKE_LOOPS / 2;
    while (!endLoops && System.currentTimeMillis() < _end/*&&
            (dtls_serverException == null) && (dtls_clientException == null)*/) {

        if (--loops < 0) {
            throw new RuntimeException(
                    "Too much loops to produce handshake packets");
        }

        ByteBuffer oNet = ByteBuffer.allocate(DTLS_BUFFER_SIZE);
        ByteBuffer oApp = ByteBuffer.allocate(0);
        SSLEngineResult r = engine.wrap(oApp, oNet);
        oNet.flip();

        SSLEngineResult.Status rs = r.getStatus();
        SSLEngineResult.HandshakeStatus hs = r.getHandshakeStatus();
        logger.debug("DTLS " + side + ": " + "----produce handshake packet(" +
                loops + ", " + rs + ", " + hs + ")----");
        if (rs == SSLEngineResult.Status.BUFFER_OVERFLOW) {
            // the client maximum fragment size config does not work?
            throw new Exception("Buffer overflow: " +
                        "incorrect server maximum fragment size");
        } else if (rs == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
            logger.debug("DTLS " + side + ": " +
                    "Produce handshake packets: BUFFER_UNDERFLOW occured");
            logger.debug("DTLS " + side + ": " +
                    "Produce handshake packets: Handshake status: " + hs);
            // bad packet, or the client maximum fragment size
            // config does not work?
            if (hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
                throw new Exception("Buffer underflow: " +
                        "incorrect server maximum fragment size");
            } // otherwise, ignore this packet
        } else if (rs == SSLEngineResult.Status.CLOSED) {
            throw new Exception("SSLEngine has closed");
        } else if (rs == SSLEngineResult.Status.OK) {
            // OK
        } else {
            throw new Exception("Can't reach here, result is " + rs);
        }

        // SSLEngineResult.Status.OK:
        if (oNet.hasRemaining()) {
            byte[] ba = new byte[oNet.remaining()];
            oNet.get(ba);
            DatagramOverDiameterPacket packet = createHandshakePacket(ba, peer_realm);
            packets.add(packet);
        }

        if (hs == SSLEngineResult.HandshakeStatus.FINISHED) {
            logger.debug("DTLS " + side + ": " + "Produce handshake packets: "
                        + "Handshake status is FINISHED, finish the loop");
            return true;
        }

        boolean endInnerLoop = false;
        SSLEngineResult.HandshakeStatus nhs = hs;
        while (!endInnerLoop) {
            if (nhs == SSLEngineResult.HandshakeStatus.NEED_TASK) {
                dtls_runDelegatedTasks(engine);
            } else if (nhs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP ||
                nhs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP_AGAIN ||
                nhs == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {

                endInnerLoop = true;
                endLoops = true;
            } else if (nhs == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
                endInnerLoop = true;
            } else if (nhs == SSLEngineResult.HandshakeStatus.FINISHED) {
                throw new Exception(
                        "Unexpected status, SSLEngine.getHandshakeStatus() "
                                + "shouldn't return FINISHED");
            } else {
                throw new Exception("Can't reach here, handshake status is "
                        + nhs);
            }
            nhs = engine.getHandshakeStatus();
        }
    }

    return false;
}
 
Example 18
Source File: GelfTCPSSLSender.java    From xian with Apache License 2.0 4 votes vote down vote up
private void doHandshake(SocketChannel socketChannel, SSLEngine sslEngine, ByteBuffer myNetData, ByteBuffer peerNetData)
        throws IOException {

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

    SSLEngineResult.HandshakeStatus hs = sslEngine.getHandshakeStatus();

    // Process handshaking message
    while (hs != SSLEngineResult.HandshakeStatus.FINISHED && hs != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {

        switch (hs) {

            case NEED_UNWRAP:
                // Receive handshaking data from peer
                if (socketChannel.read(peerNetData) < 0) {
                    throw new SocketException("Channel closed");
                }

                // Process incoming handshaking data
                peerNetData.flip();
                SSLEngineResult res = sslEngine.unwrap(peerNetData, peerAppData);
                peerNetData.compact();
                hs = res.getHandshakeStatus();

                // Check status
                switch (res.getStatus()) {
                    case OK:
                        // Handle OK status
                        break;
                    case BUFFER_OVERFLOW:
                        peerAppData = enlargeBuffer(peerNetData, peerAppData);
                        break;

                    case BUFFER_UNDERFLOW:

                        break;
                }
                break;

            case NEED_WRAP:
                // Empty the local network packet buffer.
                myNetData.clear();

                // Generate handshaking data
                res = sslEngine.wrap(myAppData, myNetData);
                hs = res.getHandshakeStatus();

                // Check status
                switch (res.getStatus()) {
                    case OK:
                        myNetData.flip();

                        // Send the handshaking data to peer
                        while (myNetData.hasRemaining()) {
                            if (socketChannel.write(myNetData) < 0) {
                                // Handle closed channel
                            }
                        }
                        break;
                    case BUFFER_OVERFLOW:
                        myNetData = enlargeBuffer(myAppData, myNetData);
                        break;

                    case BUFFER_UNDERFLOW:
                        break;
                    case CLOSED:

                        if (sslEngine.isOutboundDone()) {
                            return;
                        } else {
                            sslEngine.closeOutbound();
                            hs = sslEngine.getHandshakeStatus();
                            break;
                        }

                    default:
                        throw new IOException("Cannot wrap data: " + res.getStatus());

                }
                break;

            case NEED_TASK:
                Runnable task;
                while ((task = sslEngine.getDelegatedTask()) != null) {
                    task.run();
                }
                hs = sslEngine.getHandshakeStatus();
                break;

            case FINISHED:
                return;
        }
    }
}