javax.net.ssl.SSLEngine#unwrap ( )源码实例Demo

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

源代码1 项目: qpid-broker-j   文件: QpidByteBufferFactory.java
static SSLEngineResult decryptSSL(final SSLEngine engine, final QpidByteBuffer src, final QpidByteBuffer dst)
        throws SSLException
{
    if (src instanceof SingleQpidByteBuffer)
    {
        ByteBuffer underlying = ((SingleQpidByteBuffer)src).getUnderlyingBuffer();
        if (dst instanceof SingleQpidByteBuffer)
        {
            return engine.unwrap(underlying, ((SingleQpidByteBuffer) dst).getUnderlyingBuffer());
        }
        else if (dst instanceof MultiQpidByteBuffer)
        {
            return engine.unwrap(underlying, ((MultiQpidByteBuffer) dst).getUnderlyingBuffers());
        }
        else
        {
            throw new IllegalStateException("unknown QBB implementation");
        }
    }
    else
    {
        throw new IllegalStateException("Source QBB can only be single byte buffer");
    }
}
 
private void checkBufferOverflowOnUnWrap(SSLEngine wrappingEngine,
        SSLEngine unwrappingEngine)
        throws SSLException {
    String wrapperMode = wrappingEngine.getUseClientMode() ? "client"
            : "server";
    String unwrapperMode = unwrappingEngine.getUseClientMode() ? "client"
            : "server";
    if (wrapperMode.equals(unwrapperMode)) {
        throw new Error("Test error: both engines are in the same mode!");
    }
    System.out.println("================================================="
            + "===========");
    System.out.println("Testing SSLEngine buffer overflow"
            + " on unwrap by " + unwrapperMode);
    ByteBuffer app = ByteBuffer.wrap(MESSAGE.getBytes());
    ByteBuffer net = ByteBuffer
            .allocate(wrappingEngine.getSession().getPacketBufferSize());
    SSLEngineResult r = wrappingEngine.wrap(app, net);
    checkResult(r, SSLEngineResult.Status.OK);
    //Making app buffer size less than required by 1 byte.
    app = ByteBuffer.allocate(MESSAGE.length() - 1);
    net.flip();
    r = unwrappingEngine.unwrap(net, app);
    checkResult(r, SSLEngineResult.Status.BUFFER_OVERFLOW);
    System.out.println("Passed");
}
 
private void checkBufferUnderflowOnUnWrap(SSLEngine wrappingEngine,
        SSLEngine unwrappingEngine)
        throws SSLException {
    String wrapperMode = wrappingEngine.getUseClientMode() ? "client"
            : "server";
    String unwrapperMode = unwrappingEngine.getUseClientMode() ? "client"
            : "server";
    if (wrapperMode.equals(unwrapperMode)) {
        throw new Error("Test error: both engines are in the same mode!");
    }
    System.out.println("================================================="
            + "===========");
    System.out.println("Testing SSLEngine buffer underflow"
            + " on unwrap by " + unwrapperMode);
    ByteBuffer app = ByteBuffer.wrap(MESSAGE.getBytes());
    ByteBuffer net = ByteBuffer
            .allocate(wrappingEngine.getSession().getPacketBufferSize());
    SSLEngineResult r = wrappingEngine.wrap(app, net);
    checkResult(r, SSLEngineResult.Status.OK);
    app = ByteBuffer.allocate(unwrappingEngine.getSession()
            .getApplicationBufferSize());
    net.flip();
    //Making net buffer size less than size of dtls message.
    net.limit(net.limit() - 1);
    r = unwrappingEngine.unwrap(net, app);
    checkResult(r, SSLEngineResult.Status.BUFFER_UNDERFLOW);
    System.out.println("Passed");
}
 
源代码4 项目: SigFW   文件: DiameterFirewall.java
/**
 * DTLS decrypt byte buffer
 */
boolean diameterDTLSDecryptBuffer(SSLEngine engine, ByteBuffer source, ByteBuffer recBuffer) throws Exception {
 
    //printHex("Received application data for Decrypt", source);
    
    SSLEngineResult r = engine.unwrap(source, recBuffer);
    recBuffer.flip();
    
    SSLEngineResult.Status rs = r.getStatus();
    if (rs == SSLEngineResult.Status.BUFFER_OVERFLOW) {
        // the client maximum fragment size config does not work?
        logger.warn("Buffer overflow: " + "incorrect server maximum fragment size");
        return false;
    } else if (rs == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
        // unlikely
        logger.warn("Buffer underflow during wraping");
        return false;
    } else if (rs == SSLEngineResult.Status.CLOSED) {
        logger.warn("SSLEngine has closed");
        return false;
    } else if (rs == SSLEngineResult.Status.OK) {
        // OK
    } else {
        logger.warn("Can't reach here, result is " + rs);
        return false;
    }
    
    //printHex("Produced application data by Decrypt", recBuffer);
    return true;
}
 
源代码5 项目: dragonwell8_jdk   文件: TestTLS12.java
public static void run() throws Exception {
    SSLEngine[][] enginesToTest = getSSLEnginesToTest();

    for (SSLEngine[] engineToTest : enginesToTest) {

        SSLEngine clientSSLEngine = engineToTest[0];
        SSLEngine serverSSLEngine = engineToTest[1];

        // SSLEngine code based on RedhandshakeFinished.java

        boolean dataDone = false;

        ByteBuffer clientOut = null;
        ByteBuffer clientIn = null;
        ByteBuffer serverOut = null;
        ByteBuffer serverIn = null;
        ByteBuffer cTOs;
        ByteBuffer sTOc;

        SSLSession session = clientSSLEngine.getSession();
        int appBufferMax = session.getApplicationBufferSize();
        int netBufferMax = session.getPacketBufferSize();

        clientIn = ByteBuffer.allocate(appBufferMax + 50);
        serverIn = ByteBuffer.allocate(appBufferMax + 50);

        cTOs = ByteBuffer.allocateDirect(netBufferMax);
        sTOc = ByteBuffer.allocateDirect(netBufferMax);

        clientOut = ByteBuffer.wrap(
                "Hi Server, I'm Client".getBytes());
        serverOut = ByteBuffer.wrap(
                "Hello Client, I'm Server".getBytes());

        SSLEngineResult clientResult;
        SSLEngineResult serverResult;

        while (!dataDone) {
            clientResult = clientSSLEngine.wrap(clientOut, cTOs);
            runDelegatedTasks(clientResult, clientSSLEngine);
            serverResult = serverSSLEngine.wrap(serverOut, sTOc);
            runDelegatedTasks(serverResult, serverSSLEngine);
            cTOs.flip();
            sTOc.flip();

            if (enableDebug) {
                System.out.println("Client -> Network");
                printTlsNetworkPacket("", cTOs);
                System.out.println("");
                System.out.println("Server -> Network");
                printTlsNetworkPacket("", sTOc);
                System.out.println("");
            }

            clientResult = clientSSLEngine.unwrap(sTOc, clientIn);
            runDelegatedTasks(clientResult, clientSSLEngine);
            serverResult = serverSSLEngine.unwrap(cTOs, serverIn);
            runDelegatedTasks(serverResult, serverSSLEngine);

            cTOs.compact();
            sTOc.compact();

            if (!dataDone &&
                    (clientOut.limit() == serverIn.position()) &&
                    (serverOut.limit() == clientIn.position())) {
                checkTransfer(serverOut, clientIn);
                checkTransfer(clientOut, serverIn);
                dataDone = true;
            }
        }
    }
}
 
源代码6 项目: netty-4.1.22   文件: OpenSslEngineTest.java
@Test
public void testMultipleRecordsInOneBufferWithNonZeroPositionJDKCompatabilityModeOff() 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 {
        // Choose buffer size small enough that we can put multiple buffers into one buffer and pass it into the
        // unwrap call without exceed MAX_ENCRYPTED_PACKET_LENGTH.
        final int plainClientOutLen = 1024;
        ByteBuffer plainClientOut = allocateBuffer(plainClientOutLen);
        ByteBuffer plainServerOut = allocateBuffer(server.getSession().getApplicationBufferSize());

        ByteBuffer encClientToServer = allocateBuffer(client.getSession().getPacketBufferSize());

        int positionOffset = 1;
        // We need to be able to hold 2 records + positionOffset
        ByteBuffer combinedEncClientToServer = allocateBuffer(
                encClientToServer.capacity() * 2 + positionOffset);
        combinedEncClientToServer.position(positionOffset);

        handshake(client, server);

        plainClientOut.limit(plainClientOut.capacity());
        SSLEngineResult result = client.wrap(plainClientOut, encClientToServer);
        assertEquals(plainClientOut.capacity(), result.bytesConsumed());
        assertTrue(result.bytesProduced() > 0);

        encClientToServer.flip();

        // Copy the first record into the combined buffer
        combinedEncClientToServer.put(encClientToServer);

        plainClientOut.clear();
        encClientToServer.clear();

        result = client.wrap(plainClientOut, encClientToServer);
        assertEquals(plainClientOut.capacity(), result.bytesConsumed());
        assertTrue(result.bytesProduced() > 0);

        encClientToServer.flip();

        // Copy the first record into the combined buffer
        combinedEncClientToServer.put(encClientToServer);

        encClientToServer.clear();

        combinedEncClientToServer.flip();
        combinedEncClientToServer.position(positionOffset);

        // Make sure the limit takes positionOffset into account to the content we are looking at is correct.
        combinedEncClientToServer.limit(
                combinedEncClientToServer.limit() - positionOffset);
        final int combinedEncClientToServerLen = combinedEncClientToServer.remaining();

        result = server.unwrap(combinedEncClientToServer, plainServerOut);
        assertEquals(0, combinedEncClientToServer.remaining());
        assertEquals(combinedEncClientToServerLen, result.bytesConsumed());
        assertEquals(plainClientOutLen, result.bytesProduced());
    } finally {
        cert.delete();
        cleanupClientSslEngine(client);
        cleanupServerSslEngine(server);
    }
}
 
源代码7 项目: netty-4.1.22   文件: OpenSslEngineTest.java
@Test
public void testInputTooBigAndFillsUpBuffersJDKCompatabilityModeOff() 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(MAX_PLAINTEXT_LENGTH + 100);
        ByteBuffer plainClient2 = allocateBuffer(512);
        ByteBuffer plainClientTotal = allocateBuffer(plainClient.capacity() + plainClient2.capacity());
        plainClientTotal.put(plainClient);
        plainClientTotal.put(plainClient2);
        plainClient.clear();
        plainClient2.clear();
        plainClientTotal.flip();

        // The capacity is designed to trigger an overflow condition.
        ByteBuffer encClientToServerTooSmall = allocateBuffer(MAX_PLAINTEXT_LENGTH + 28);
        ByteBuffer encClientToServer = allocateBuffer(client.getSession().getApplicationBufferSize());
        ByteBuffer encClientToServerTotal = allocateBuffer(client.getSession().getApplicationBufferSize() << 1);
        ByteBuffer plainServer = allocateBuffer(server.getSession().getApplicationBufferSize() << 1);

        handshake(client, server);

        int plainClientRemaining = plainClient.remaining();
        int encClientToServerTooSmallRemaining = encClientToServerTooSmall.remaining();
        SSLEngineResult result = client.wrap(plainClient, encClientToServerTooSmall);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertEquals(plainClientRemaining - plainClient.remaining(), result.bytesConsumed());
        assertEquals(encClientToServerTooSmallRemaining - encClientToServerTooSmall.remaining(),
                result.bytesProduced());

        result = client.wrap(plainClient, encClientToServerTooSmall);
        assertEquals(SSLEngineResult.Status.BUFFER_OVERFLOW, result.getStatus());
        assertEquals(0, result.bytesConsumed());
        assertEquals(0, result.bytesProduced());

        plainClientRemaining = plainClient.remaining();
        int encClientToServerRemaining = encClientToServer.remaining();
        result = client.wrap(plainClient, encClientToServer);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertEquals(plainClientRemaining, result.bytesConsumed());
        assertEquals(encClientToServerRemaining - encClientToServer.remaining(), result.bytesProduced());
        assertEquals(0, plainClient.remaining());

        final int plainClient2Remaining = plainClient2.remaining();
        encClientToServerRemaining = encClientToServer.remaining();
        result = client.wrap(plainClient2, encClientToServer);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertEquals(plainClient2Remaining, result.bytesConsumed());
        assertEquals(encClientToServerRemaining - encClientToServer.remaining(), result.bytesProduced());

        // Concatenate the too small buffer
        encClientToServerTooSmall.flip();
        encClientToServer.flip();
        encClientToServerTotal.put(encClientToServerTooSmall);
        encClientToServerTotal.put(encClientToServer);
        encClientToServerTotal.flip();

        // Unwrap in a single call.
        final int encClientToServerTotalRemaining = encClientToServerTotal.remaining();
        result = server.unwrap(encClientToServerTotal, plainServer);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertEquals(encClientToServerTotalRemaining, result.bytesConsumed());
        plainServer.flip();
        assertEquals(plainClientTotal, plainServer);
    } finally {
        cert.delete();
        cleanupClientSslEngine(client);
        cleanupServerSslEngine(server);
    }
}
 
源代码8 项目: FoxTelem   文件: ExportControlled.java
/**
 * 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;
        }
    }
}
 
源代码9 项目: 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);
    }
}
 
源代码10 项目: netty-4.1.22   文件: SSLEngineTest.java
protected void handshake(SSLEngine clientEngine, SSLEngine serverEngine) throws SSLException {
    ByteBuffer cTOs = allocateBuffer(clientEngine.getSession().getPacketBufferSize());
    ByteBuffer sTOc = allocateBuffer(serverEngine.getSession().getPacketBufferSize());

    ByteBuffer serverAppReadBuffer = allocateBuffer(
            serverEngine.getSession().getApplicationBufferSize());
    ByteBuffer clientAppReadBuffer = allocateBuffer(
            clientEngine.getSession().getApplicationBufferSize());

    clientEngine.beginHandshake();
    serverEngine.beginHandshake();

    ByteBuffer empty = allocateBuffer(0);

    SSLEngineResult clientResult;
    SSLEngineResult serverResult;

    boolean clientHandshakeFinished = false;
    boolean serverHandshakeFinished = false;

    do {
        int cTOsPos = cTOs.position();
        int sTOcPos = sTOc.position();

        if (!clientHandshakeFinished) {
            clientResult = clientEngine.wrap(empty, cTOs);
            runDelegatedTasks(clientResult, clientEngine);
            assertEquals(empty.remaining(), clientResult.bytesConsumed());
            assertEquals(cTOs.position() - cTOsPos,  clientResult.bytesProduced());

            if (isHandshakeFinished(clientResult)) {
                clientHandshakeFinished = true;
            }
        }

        if (!serverHandshakeFinished) {
            serverResult = serverEngine.wrap(empty, sTOc);
            runDelegatedTasks(serverResult, serverEngine);
            assertEquals(empty.remaining(), serverResult.bytesConsumed());
            assertEquals(sTOc.position() - sTOcPos, serverResult.bytesProduced());

            if (isHandshakeFinished(serverResult)) {
                serverHandshakeFinished = true;
            }
        }

        cTOs.flip();
        sTOc.flip();

        cTOsPos = cTOs.position();
        sTOcPos = sTOc.position();

        if (!clientHandshakeFinished) {
            int clientAppReadBufferPos = clientAppReadBuffer.position();
            clientResult = clientEngine.unwrap(sTOc, clientAppReadBuffer);

            runDelegatedTasks(clientResult, clientEngine);
            assertEquals(sTOc.position() - sTOcPos, clientResult.bytesConsumed());
            assertEquals(clientAppReadBuffer.position() - clientAppReadBufferPos, clientResult.bytesProduced());

            if (isHandshakeFinished(clientResult)) {
                clientHandshakeFinished = true;
            }
        } else {
            assertFalse(sTOc.hasRemaining());
        }

        if (!serverHandshakeFinished) {
            int serverAppReadBufferPos = serverAppReadBuffer.position();
            serverResult = serverEngine.unwrap(cTOs, serverAppReadBuffer);
            runDelegatedTasks(serverResult, serverEngine);
            assertEquals(cTOs.position() - cTOsPos, serverResult.bytesConsumed());
            assertEquals(serverAppReadBuffer.position() - serverAppReadBufferPos, serverResult.bytesProduced());

            if (isHandshakeFinished(serverResult)) {
                serverHandshakeFinished = true;
            }
        } else {
            assertFalse(cTOs.hasRemaining());
        }

        sTOc.compact();
        cTOs.compact();
    } while (!clientHandshakeFinished || !serverHandshakeFinished);
}
 
源代码11 项目: netty-4.1.22   文件: SSLEngineTest.java
@Test
public void testMultipleRecordsInOneBufferWithNonZeroPosition() throws Exception {
    SelfSignedCertificate cert = new SelfSignedCertificate();

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

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

    try {
        // Choose buffer size small enough that we can put multiple buffers into one buffer and pass it into the
        // unwrap call without exceed MAX_ENCRYPTED_PACKET_LENGTH.
        ByteBuffer plainClientOut = allocateBuffer(1024);
        ByteBuffer plainServerOut = allocateBuffer(server.getSession().getApplicationBufferSize());

        ByteBuffer encClientToServer = allocateBuffer(client.getSession().getPacketBufferSize());

        int positionOffset = 1;
        // We need to be able to hold 2 records + positionOffset
        ByteBuffer combinedEncClientToServer = allocateBuffer(
                encClientToServer.capacity() * 2 + positionOffset);
        combinedEncClientToServer.position(positionOffset);

        handshake(client, server);

        plainClientOut.limit(plainClientOut.capacity());
        SSLEngineResult result = client.wrap(plainClientOut, encClientToServer);
        assertEquals(plainClientOut.capacity(), result.bytesConsumed());
        assertTrue(result.bytesProduced() > 0);

        encClientToServer.flip();

        // Copy the first record into the combined buffer
        combinedEncClientToServer.put(encClientToServer);

        plainClientOut.clear();
        encClientToServer.clear();

        result = client.wrap(plainClientOut, encClientToServer);
        assertEquals(plainClientOut.capacity(), result.bytesConsumed());
        assertTrue(result.bytesProduced() > 0);

        encClientToServer.flip();

        int encClientToServerLen = encClientToServer.remaining();

        // Copy the first record into the combined buffer
        combinedEncClientToServer.put(encClientToServer);

        encClientToServer.clear();

        combinedEncClientToServer.flip();
        combinedEncClientToServer.position(positionOffset);

        // Ensure we have the first record and a tiny amount of the second record in the buffer
        combinedEncClientToServer.limit(
                combinedEncClientToServer.limit() - (encClientToServerLen - positionOffset));
        result = server.unwrap(combinedEncClientToServer, plainServerOut);
        assertEquals(encClientToServerLen, result.bytesConsumed());
        assertTrue(result.bytesProduced() > 0);
    } finally {
        cert.delete();
        cleanupClientSslEngine(client);
        cleanupServerSslEngine(server);
    }
}
 
源代码12 项目: netty-4.1.22   文件: SSLEngineTest.java
@Test
public void testMultipleRecordsInOneBufferBiggerThenPacketBufferSize() throws Exception {
    SelfSignedCertificate cert = new SelfSignedCertificate();

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

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

    try {
        ByteBuffer plainClientOut = allocateBuffer(4096);
        ByteBuffer plainServerOut = allocateBuffer(server.getSession().getApplicationBufferSize());

        ByteBuffer encClientToServer = allocateBuffer(server.getSession().getPacketBufferSize() * 2);

        handshake(client, server);

        int srcLen = plainClientOut.remaining();
        SSLEngineResult result;

        while (encClientToServer.position() <= server.getSession().getPacketBufferSize()) {
            result = client.wrap(plainClientOut, encClientToServer);
            assertEquals(SSLEngineResult.Status.OK, result.getStatus());
            assertEquals(srcLen, result.bytesConsumed());
            assertTrue(result.bytesProduced() > 0);

            plainClientOut.clear();
        }

        encClientToServer.flip();

        result = server.unwrap(encClientToServer, plainServerOut);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertTrue(result.bytesConsumed() > 0);
        assertTrue(result.bytesProduced() > 0);
    } finally {
        cert.delete();
        cleanupClientSslEngine(client);
        cleanupServerSslEngine(server);
    }
}
 
源代码13 项目: netty-4.1.22   文件: SSLEngineTest.java
@Test
public void testBufferUnderFlow() throws Exception {
    SelfSignedCertificate cert = new SelfSignedCertificate();

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

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

    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(SSL_RECORD_HEADER_LENGTH - 1);
        result = server.unwrap(encClientToServer, plainServer);
        assertResultIsBufferUnderflow(result);

        // We limit the buffer so we can read the header but not the rest, this should result in an
        // BUFFER_UNDERFLOW.
        encClientToServer.limit(SSL_RECORD_HEADER_LENGTH);
        result = server.unwrap(encClientToServer, plainServer);
        assertResultIsBufferUnderflow(result);

        // We limit the buffer so we can read the header and partly the rest, this should result in an
        // BUFFER_UNDERFLOW.
        encClientToServer.limit(SSL_RECORD_HEADER_LENGTH  + remaining - 1 - SSL_RECORD_HEADER_LENGTH);
        result = server.unwrap(encClientToServer, plainServer);
        assertResultIsBufferUnderflow(result);

        // Reset limit so we can read the full record.
        encClientToServer.limit(remaining);

        result = server.unwrap(encClientToServer, plainServer);
        assertEquals(SSLEngineResult.Status.OK, result.getStatus());
        assertEquals(result.bytesConsumed(), remaining);
        assertTrue(result.bytesProduced() > 0);
    } finally {
        cert.delete();
        cleanupClientSslEngine(client);
        cleanupServerSslEngine(server);
    }
}
 
源代码14 项目: TencentKona-8   文件: TestTLS12.java
public static void run() throws Exception {
    SSLEngine[][] enginesToTest = getSSLEnginesToTest();

    for (SSLEngine[] engineToTest : enginesToTest) {

        SSLEngine clientSSLEngine = engineToTest[0];
        SSLEngine serverSSLEngine = engineToTest[1];

        // SSLEngine code based on RedhandshakeFinished.java

        boolean dataDone = false;

        ByteBuffer clientOut = null;
        ByteBuffer clientIn = null;
        ByteBuffer serverOut = null;
        ByteBuffer serverIn = null;
        ByteBuffer cTOs;
        ByteBuffer sTOc;

        SSLSession session = clientSSLEngine.getSession();
        int appBufferMax = session.getApplicationBufferSize();
        int netBufferMax = session.getPacketBufferSize();

        clientIn = ByteBuffer.allocate(appBufferMax + 50);
        serverIn = ByteBuffer.allocate(appBufferMax + 50);

        cTOs = ByteBuffer.allocateDirect(netBufferMax);
        sTOc = ByteBuffer.allocateDirect(netBufferMax);

        clientOut = ByteBuffer.wrap(
                "Hi Server, I'm Client".getBytes());
        serverOut = ByteBuffer.wrap(
                "Hello Client, I'm Server".getBytes());

        SSLEngineResult clientResult;
        SSLEngineResult serverResult;

        while (!dataDone) {
            clientResult = clientSSLEngine.wrap(clientOut, cTOs);
            runDelegatedTasks(clientResult, clientSSLEngine);
            serverResult = serverSSLEngine.wrap(serverOut, sTOc);
            runDelegatedTasks(serverResult, serverSSLEngine);
            cTOs.flip();
            sTOc.flip();

            if (enableDebug) {
                System.out.println("Client -> Network");
                printTlsNetworkPacket("", cTOs);
                System.out.println("");
                System.out.println("Server -> Network");
                printTlsNetworkPacket("", sTOc);
                System.out.println("");
            }

            clientResult = clientSSLEngine.unwrap(sTOc, clientIn);
            runDelegatedTasks(clientResult, clientSSLEngine);
            serverResult = serverSSLEngine.unwrap(cTOs, serverIn);
            runDelegatedTasks(serverResult, serverSSLEngine);

            cTOs.compact();
            sTOc.compact();

            if (!dataDone &&
                    (clientOut.limit() == serverIn.position()) &&
                    (serverOut.limit() == clientIn.position())) {
                checkTransfer(serverOut, clientIn);
                checkTransfer(clientOut, serverIn);
                dataDone = true;
            }
        }
    }
}
 
源代码15 项目: jdk8u_jdk   文件: TestTLS12.java
public static void run() throws Exception {
    SSLEngine[][] enginesToTest = getSSLEnginesToTest();

    for (SSLEngine[] engineToTest : enginesToTest) {

        SSLEngine clientSSLEngine = engineToTest[0];
        SSLEngine serverSSLEngine = engineToTest[1];

        // SSLEngine code based on RedhandshakeFinished.java

        boolean dataDone = false;

        ByteBuffer clientOut = null;
        ByteBuffer clientIn = null;
        ByteBuffer serverOut = null;
        ByteBuffer serverIn = null;
        ByteBuffer cTOs;
        ByteBuffer sTOc;

        SSLSession session = clientSSLEngine.getSession();
        int appBufferMax = session.getApplicationBufferSize();
        int netBufferMax = session.getPacketBufferSize();

        clientIn = ByteBuffer.allocate(appBufferMax + 50);
        serverIn = ByteBuffer.allocate(appBufferMax + 50);

        cTOs = ByteBuffer.allocateDirect(netBufferMax);
        sTOc = ByteBuffer.allocateDirect(netBufferMax);

        clientOut = ByteBuffer.wrap(
                "Hi Server, I'm Client".getBytes());
        serverOut = ByteBuffer.wrap(
                "Hello Client, I'm Server".getBytes());

        SSLEngineResult clientResult;
        SSLEngineResult serverResult;

        while (!dataDone) {
            clientResult = clientSSLEngine.wrap(clientOut, cTOs);
            runDelegatedTasks(clientResult, clientSSLEngine);
            serverResult = serverSSLEngine.wrap(serverOut, sTOc);
            runDelegatedTasks(serverResult, serverSSLEngine);
            cTOs.flip();
            sTOc.flip();

            if (enableDebug) {
                System.out.println("Client -> Network");
                printTlsNetworkPacket("", cTOs);
                System.out.println("");
                System.out.println("Server -> Network");
                printTlsNetworkPacket("", sTOc);
                System.out.println("");
            }

            clientResult = clientSSLEngine.unwrap(sTOc, clientIn);
            runDelegatedTasks(clientResult, clientSSLEngine);
            serverResult = serverSSLEngine.unwrap(cTOs, serverIn);
            runDelegatedTasks(serverResult, serverSSLEngine);

            cTOs.compact();
            sTOc.compact();

            if (!dataDone &&
                    (clientOut.limit() == serverIn.position()) &&
                    (serverOut.limit() == clientIn.position())) {
                checkTransfer(serverOut, clientIn);
                checkTransfer(clientOut, serverIn);
                dataDone = true;
            }
        }
    }
}
 
源代码16 项目: openjdk-jdk8u   文件: TestTLS12.java
public static void run() throws Exception {
    SSLEngine[][] enginesToTest = getSSLEnginesToTest();

    for (SSLEngine[] engineToTest : enginesToTest) {

        SSLEngine clientSSLEngine = engineToTest[0];
        SSLEngine serverSSLEngine = engineToTest[1];

        // SSLEngine code based on RedhandshakeFinished.java

        boolean dataDone = false;

        ByteBuffer clientOut = null;
        ByteBuffer clientIn = null;
        ByteBuffer serverOut = null;
        ByteBuffer serverIn = null;
        ByteBuffer cTOs;
        ByteBuffer sTOc;

        SSLSession session = clientSSLEngine.getSession();
        int appBufferMax = session.getApplicationBufferSize();
        int netBufferMax = session.getPacketBufferSize();

        clientIn = ByteBuffer.allocate(appBufferMax + 50);
        serverIn = ByteBuffer.allocate(appBufferMax + 50);

        cTOs = ByteBuffer.allocateDirect(netBufferMax);
        sTOc = ByteBuffer.allocateDirect(netBufferMax);

        clientOut = ByteBuffer.wrap(
                "Hi Server, I'm Client".getBytes());
        serverOut = ByteBuffer.wrap(
                "Hello Client, I'm Server".getBytes());

        SSLEngineResult clientResult;
        SSLEngineResult serverResult;

        while (!dataDone) {
            clientResult = clientSSLEngine.wrap(clientOut, cTOs);
            runDelegatedTasks(clientResult, clientSSLEngine);
            serverResult = serverSSLEngine.wrap(serverOut, sTOc);
            runDelegatedTasks(serverResult, serverSSLEngine);
            cTOs.flip();
            sTOc.flip();

            if (enableDebug) {
                System.out.println("Client -> Network");
                printTlsNetworkPacket("", cTOs);
                System.out.println("");
                System.out.println("Server -> Network");
                printTlsNetworkPacket("", sTOc);
                System.out.println("");
            }

            clientResult = clientSSLEngine.unwrap(sTOc, clientIn);
            runDelegatedTasks(clientResult, clientSSLEngine);
            serverResult = serverSSLEngine.unwrap(cTOs, serverIn);
            runDelegatedTasks(serverResult, serverSSLEngine);

            cTOs.compact();
            sTOc.compact();

            if (!dataDone &&
                    (clientOut.limit() == serverIn.position()) &&
                    (serverOut.limit() == clientIn.position())) {
                checkTransfer(serverOut, clientIn);
                checkTransfer(clientOut, serverIn);
                dataDone = true;
            }
        }
    }
}
 
源代码17 项目: an2linuxclient   文件: TlsHelper.java
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;
    }
}
 
源代码18 项目: lams   文件: ExportControlled.java
/**
 * 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;
        }
    }
}
 
源代码19 项目: cloudstack   文件: Link.java
private static HandshakeHolder doHandshakeUnwrap(final SocketChannel socketChannel, final SSLEngine sslEngine,
                                         ByteBuffer peerAppData, ByteBuffer peerNetData, final int appBufferSize) throws IOException {
    if (socketChannel == null || sslEngine == null || peerAppData == null || peerNetData == null || appBufferSize < 0) {
        return new HandshakeHolder(peerAppData, peerNetData, false);
    }
    if (socketChannel.read(peerNetData) < 0) {
        if (sslEngine.isInboundDone() && sslEngine.isOutboundDone()) {
            return new HandshakeHolder(peerAppData, peerNetData, false);
        }
        try {
            sslEngine.closeInbound();
        } catch (SSLException e) {
            s_logger.warn("This SSL engine was forced to close inbound due to end of stream.", e);
        }
        sslEngine.closeOutbound();
        // After closeOutbound the engine will be set to WRAP state,
        // in order to try to send a close message to the client.
        return new HandshakeHolder(peerAppData, peerNetData, true);
    }
    peerNetData.flip();
    SSLEngineResult result = null;
    try {
        result = sslEngine.unwrap(peerNetData, peerAppData);
        peerNetData.compact();
    } catch (final SSLException sslException) {
        s_logger.error(String.format("SSL error caught during unwrap data: %s, for local address=%s, remote address=%s. The client may have invalid ca-certificates.",
                sslException.getMessage(), socketChannel.getLocalAddress(), socketChannel.getRemoteAddress()));
        sslEngine.closeOutbound();
        return new HandshakeHolder(peerAppData, peerNetData, false);
    }
    if (result == null) {
        return new HandshakeHolder(peerAppData, peerNetData, false);
    }
    switch (result.getStatus()) {
        case OK:
            break;
        case BUFFER_OVERFLOW:
            // Will occur when peerAppData's capacity is smaller than the data derived from peerNetData's unwrap.
            peerAppData = enlargeBuffer(peerAppData, appBufferSize);
            break;
        case BUFFER_UNDERFLOW:
            // Will occur either when no data was read from the peer or when the peerNetData buffer
            // was too small to hold all peer's data.
            peerNetData = handleBufferUnderflow(sslEngine, peerNetData);
            break;
        case CLOSED:
            if (sslEngine.isOutboundDone()) {
                return new HandshakeHolder(peerAppData, peerNetData, false);
            } else {
                sslEngine.closeOutbound();
            }
            break;
        default:
            throw new IllegalStateException("Invalid SSL status: " + result.getStatus());
    }
    return new HandshakeHolder(peerAppData, peerNetData, true);
}
 
源代码20 项目: an2linuxclient   文件: TlsHelper.java
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;
    }
}