Search in sources :

Example 76 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project AndroidAsync by koush.

the class ConscryptTests method testConscryptSSLEngineNPNHandshakeBug.

public void testConscryptSSLEngineNPNHandshakeBug() throws Exception {
    //        Security.insertProviderAt(new OpenSSLProvider("MyNameBlah"), 1);
    Context gms = getContext().createPackageContext("com.google.android.gms", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
    gms.getClassLoader().loadClass("com.google.android.gms.common.security.ProviderInstallerImpl").getMethod("insertProvider", Context.class).invoke(null, getContext());
    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(null, null, null);
    SSLEngine engine = ctx.createSSLEngine();
    configure(engine, "www.google.com", 443);
    engine.setUseClientMode(true);
    engine.beginHandshake();
    Socket socket = new Socket();
    socket.connect(new InetSocketAddress("www.google.com", 443));
    InputStream is = socket.getInputStream();
    OutputStream os = socket.getOutputStream();
    byte[] buf = new byte[65536];
    ByteBuffer unwrap = null;
    ByteBuffer dummy = ByteBuffer.allocate(65536);
    SSLEngineResult.HandshakeStatus handshakeStatus = engine.getHandshakeStatus();
    while (handshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED && handshakeStatus != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
        if (handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
            System.out.println("waiting for read... " + engine.getHandshakeStatus());
            int read = is.read(buf);
            System.out.println("read: " + read);
            if (read <= 0)
                throw new Exception("closed!");
            if (unwrap != null) {
                int bufLen = unwrap.remaining() + read;
                ByteBuffer b = ByteBuffer.allocate(bufLen);
                b.put(unwrap);
                b.put(buf, 0, read);
                b.flip();
                unwrap = b;
            } else {
                unwrap = ByteBuffer.wrap(buf, 0, read);
            }
            if (!unwrap.hasRemaining()) {
                unwrap = null;
            }
            dummy.clear();
            SSLEngineResult res = engine.unwrap(unwrap, dummy);
            System.out.println("data remaining after unwrap: " + unwrap.remaining());
            handshakeStatus = res.getHandshakeStatus();
        }
        if (handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
            dummy.clear();
            SSLEngineResult res = engine.wrap(ByteBuffer.allocate(0), dummy);
            handshakeStatus = res.getHandshakeStatus();
            dummy.flip();
            if (dummy.hasRemaining()) {
                os.write(dummy.array(), 0, dummy.remaining());
            }
        } else if (handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_TASK) {
            engine.getDelegatedTask().run();
        }
    }
    System.out.println("Done handshaking! Thank you come again.");
    long ptr = (Long) sslNativePointer.get(engine);
    byte[] proto = (byte[]) nativeGetAlpnNegotiatedProtocol.invoke(null, ptr);
    //        byte[] proto = (byte[]) nativeGetNpnNegotiatedProtocol.invoke(null, ptr);
    String protoString = new String(proto);
    System.out.println("negotiated protocol was: " + protoString);
    assertEquals(protoString, "spdy/3.1");
    socket.close();
}
Also used : Context(android.content.Context) SSLContext(javax.net.ssl.SSLContext) SSLEngine(javax.net.ssl.SSLEngine) InetSocketAddress(java.net.InetSocketAddress) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) SSLContext(javax.net.ssl.SSLContext) ByteBuffer(java.nio.ByteBuffer) SSLEngineResult(javax.net.ssl.SSLEngineResult) Socket(java.net.Socket)

Example 77 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project Openfire by igniterealtime.

the class TLSStreamHandler method doHandshake.

private boolean doHandshake(SelectionKey sk) throws IOException {
    SSLEngineResult result;
    if (initialHSComplete) {
        return initialHSComplete;
    }
    /*
           * Flush out the outgoing buffer, if there's anything left in it.
           */
    if (outgoingNetBB.hasRemaining()) {
        if (!flush(outgoingNetBB)) {
            return false;
        }
        switch(initialHSStatus) {
            /*
                * Is this the last buffer?
                */
            case FINISHED:
                initialHSComplete = true;
            case NEED_UNWRAP:
                if (sk != null) {
                    sk.interestOps(SelectionKey.OP_READ);
                }
                break;
        }
        return initialHSComplete;
    }
    switch(initialHSStatus) {
        case NEED_UNWRAP:
            if (rbc.read(incomingNetBB) == -1) {
                try {
                    tlsEngine.closeInbound();
                } catch (javax.net.ssl.SSLException ex) {
                    // OF-1009 Process these as a 'normal' handshake rejection - it's the peer closing the connection abruptly.
                    if ("Inbound closed before receiving peer's close_notify: possible truncation attack?".equals(ex.getMessage())) {
                        throw new SSLHandshakeException("The peer closed the connection while performing a TLS handshake.");
                    }
                    throw ex;
                }
                return initialHSComplete;
            }
            needIO: while (initialHSStatus == HandshakeStatus.NEED_UNWRAP) {
                /*
                     * Don't need to resize requestBB, since no app data should be generated here.
                     */
                incomingNetBB.flip();
                result = tlsEngine.unwrap(incomingNetBB, appBB);
                incomingNetBB.compact();
                initialHSStatus = result.getHandshakeStatus();
                switch(result.getStatus()) {
                    case OK:
                        switch(initialHSStatus) {
                            case NOT_HANDSHAKING:
                                throw new IOException("Not handshaking during initial handshake");
                            case NEED_TASK:
                                initialHSStatus = doTasks();
                                break;
                            case FINISHED:
                                initialHSComplete = true;
                                break needIO;
                        }
                        break;
                    case BUFFER_UNDERFLOW:
                        /*
                          * Need to go reread the Channel for more data.
                          */
                        if (sk != null) {
                            sk.interestOps(SelectionKey.OP_READ);
                        }
                        break needIO;
                    default:
                        // BUFFER_OVERFLOW/CLOSED:
                        throw new IOException("Received" + result.getStatus() + "during initial handshaking");
                }
            }
            /*
                * Just transitioned from read to write.
                */
            if (initialHSStatus != HandshakeStatus.NEED_WRAP) {
                break;
            }
        case NEED_WRAP:
            /*
                * The flush above guarantees the out buffer to be empty
                */
            outgoingNetBB.clear();
            result = tlsEngine.wrap(hsBB, outgoingNetBB);
            outgoingNetBB.flip();
            initialHSStatus = result.getHandshakeStatus();
            switch(result.getStatus()) {
                case OK:
                    if (initialHSStatus == HandshakeStatus.NEED_TASK) {
                        initialHSStatus = doTasks();
                    }
                    if (sk != null) {
                        sk.interestOps(SelectionKey.OP_WRITE);
                    }
                    break;
                default:
                    // BUFFER_OVERFLOW/BUFFER_UNDERFLOW/CLOSED:
                    throw new IOException("Received" + result.getStatus() + "during initial handshaking");
            }
            break;
        default:
            // NOT_HANDSHAKING/NEED_TASK/FINISHED
            throw new RuntimeException("Invalid Handshaking State" + initialHSStatus);
    }
    return initialHSComplete;
}
Also used : SSLEngineResult(javax.net.ssl.SSLEngineResult) IOException(java.io.IOException) SSLHandshakeException(javax.net.ssl.SSLHandshakeException)

Example 78 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project jetty.project by eclipse.

the class SelectChannelEndPointSslTest method testTcpClose.

@Test
public void testTcpClose() throws Exception {
    // This test replaces SSLSocket() with a very manual SSL client
    // so we can close TCP underneath SSL.
    SocketChannel client = SocketChannel.open(_connector.socket().getLocalSocketAddress());
    client.socket().setSoTimeout(500);
    SocketChannel server = _connector.accept();
    server.configureBlocking(false);
    _manager.accept(server);
    SSLEngine engine = __sslCtxFactory.newSSLEngine();
    engine.setUseClientMode(true);
    engine.beginHandshake();
    ByteBuffer appOut = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize());
    ByteBuffer sslOut = ByteBuffer.allocate(engine.getSession().getPacketBufferSize() * 2);
    ByteBuffer appIn = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize());
    ByteBuffer sslIn = ByteBuffer.allocate(engine.getSession().getPacketBufferSize() * 2);
    boolean debug = false;
    if (debug)
        System.err.println(engine.getHandshakeStatus());
    int loop = 20;
    while (engine.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING) {
        if (--loop == 0)
            throw new IllegalStateException();
        if (engine.getHandshakeStatus() == HandshakeStatus.NEED_WRAP) {
            if (debug)
                System.err.printf("sslOut %d-%d-%d%n", sslOut.position(), sslOut.limit(), sslOut.capacity());
            if (debug)
                System.err.printf("appOut %d-%d-%d%n", appOut.position(), appOut.limit(), appOut.capacity());
            SSLEngineResult result = engine.wrap(appOut, sslOut);
            if (debug)
                System.err.println(result);
            sslOut.flip();
            int flushed = client.write(sslOut);
            if (debug)
                System.err.println("out=" + flushed);
            sslOut.clear();
        }
        if (engine.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP) {
            if (debug)
                System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
            if (sslIn.position() == 0) {
                int filled = client.read(sslIn);
                if (debug)
                    System.err.println("in=" + filled);
            }
            sslIn.flip();
            if (debug)
                System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
            SSLEngineResult result = engine.unwrap(sslIn, appIn);
            if (debug)
                System.err.println(result);
            if (debug)
                System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
            if (sslIn.hasRemaining())
                sslIn.compact();
            else
                sslIn.clear();
            if (debug)
                System.err.printf("sslIn %d-%d-%d%n", sslIn.position(), sslIn.limit(), sslIn.capacity());
        }
        if (engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
            Runnable task;
            while ((task = engine.getDelegatedTask()) != null) task.run();
            if (debug)
                System.err.println(engine.getHandshakeStatus());
        }
    }
    if (debug)
        System.err.println("\nSay Hello");
    // write a message
    appOut.put("HelloWorld".getBytes(StandardCharsets.UTF_8));
    appOut.flip();
    SSLEngineResult result = engine.wrap(appOut, sslOut);
    if (debug)
        System.err.println(result);
    sslOut.flip();
    int flushed = client.write(sslOut);
    if (debug)
        System.err.println("out=" + flushed);
    sslOut.clear();
    appOut.clear();
    // read the response
    int filled = client.read(sslIn);
    if (debug)
        System.err.println("in=" + filled);
    sslIn.flip();
    result = engine.unwrap(sslIn, appIn);
    if (debug)
        System.err.println(result);
    if (sslIn.hasRemaining())
        sslIn.compact();
    else
        sslIn.clear();
    appIn.flip();
    String reply = new String(appIn.array(), appIn.arrayOffset(), appIn.remaining());
    appIn.clear();
    Assert.assertEquals("HelloWorld", reply);
    if (debug)
        System.err.println("Shutting down output");
    client.socket().shutdownOutput();
    filled = client.read(sslIn);
    if (debug)
        System.err.println("in=" + filled);
    if (filled >= 0) {
        // this is the old behaviour. 
        sslIn.flip();
        try {
            // Since the client closed abruptly, the server is sending a close alert with a failure
            engine.unwrap(sslIn, appIn);
            Assert.fail();
        } catch (SSLException x) {
        // Expected
        }
    }
    sslIn.clear();
    filled = client.read(sslIn);
    Assert.assertEquals(-1, filled);
    // TODO This should not be needed
    Thread.sleep(100);
    Assert.assertFalse(server.isOpen());
}
Also used : SocketChannel(java.nio.channels.SocketChannel) SSLEngineResult(javax.net.ssl.SSLEngineResult) SSLEngine(javax.net.ssl.SSLEngine) ByteBuffer(java.nio.ByteBuffer) SSLException(javax.net.ssl.SSLException) Test(org.junit.Test)

Example 79 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project h2o-3 by h2oai.

the class SSLSocketChannel method write.

@Override
public int write(ByteBuffer src) throws IOException {
    if (closing || closed) {
        throw new IOException("Cannot perform socket write, the socket is closed (or being closed).");
    }
    int wrote = 0;
    // src can be much bigger than what our SSL session allows to send in one go
    while (src.hasRemaining()) {
        netOutBuffer.clear();
        SSLEngineResult wrapResult = sslEngine.wrap(src, netOutBuffer);
        netOutBuffer.flip();
        if (wrapResult.getStatus() == SSLEngineResult.Status.OK) {
            if (wrapResult.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK)
                tasks();
        }
        while (netOutBuffer.hasRemaining()) {
            wrote += channel.write(netOutBuffer);
        }
    }
    return wrote;
}
Also used : SSLEngineResult(javax.net.ssl.SSLEngineResult) IOException(java.io.IOException)

Example 80 with SSLEngineResult

use of javax.net.ssl.SSLEngineResult in project h2o-3 by h2oai.

the class SSLSocketChannel method handshakeUnwrap.

private synchronized SSLEngineResult handshakeUnwrap() throws IOException {
    if (netInBuffer.position() == netInBuffer.limit()) {
        netInBuffer.clear();
    }
    channel.read(netInBuffer);
    SSLEngineResult unwrapResult;
    peerAppData.clear();
    do {
        netInBuffer.flip();
        unwrapResult = sslEngine.unwrap(netInBuffer, peerAppData);
        netInBuffer.compact();
        hs = unwrapResult.getHandshakeStatus();
        switch(unwrapResult.getStatus()) {
            case OK:
            case BUFFER_UNDERFLOW:
                {
                    if (unwrapResult.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
                        tasks();
                    }
                    break;
                }
            case BUFFER_OVERFLOW:
                {
                    int applicationBufferSize = sslEngine.getSession().getApplicationBufferSize();
                    if (applicationBufferSize > peerAppData.capacity()) {
                        ByteBuffer b = ByteBuffer.allocate(applicationBufferSize + peerAppData.position());
                        peerAppData.flip();
                        b.put(peerAppData);
                        peerAppData = b;
                    } else {
                        peerAppData.compact();
                    }
                    break;
                }
            default:
                throw new IOException("Failed to SSL unwrap with status " + unwrapResult.getStatus());
        }
    } while (unwrapResult.getStatus() == SSLEngineResult.Status.OK && hs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP);
    return unwrapResult;
}
Also used : SSLEngineResult(javax.net.ssl.SSLEngineResult) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer)

Aggregations

SSLEngineResult (javax.net.ssl.SSLEngineResult)139 ByteBuffer (java.nio.ByteBuffer)53 IOException (java.io.IOException)32 SSLException (javax.net.ssl.SSLException)32 SSLEngine (javax.net.ssl.SSLEngine)25 Test (org.junit.Test)13 ReadOnlyBufferException (java.nio.ReadOnlyBufferException)12 SelfSignedCertificate (io.netty.handler.ssl.util.SelfSignedCertificate)10 HandshakeStatus (javax.net.ssl.SSLEngineResult.HandshakeStatus)9 EOFException (java.io.EOFException)7 ByteBuf (io.netty.buffer.ByteBuf)6 SSLSession (javax.net.ssl.SSLSession)6 WritePendingException (java.nio.channels.WritePendingException)5 KeyManagementException (java.security.KeyManagementException)5 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)5 ExecutionException (java.util.concurrent.ExecutionException)5 TimeoutException (java.util.concurrent.TimeoutException)5 Status (javax.net.ssl.SSLEngineResult.Status)5 CompositeByteBuf (io.netty.buffer.CompositeByteBuf)4 BufferUnderflowException (java.nio.BufferUnderflowException)3