/*
 * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

//
// SunJSSE does not support dynamic system properties, no way to re-use
// system properties in samevm/agentvm mode.
//

/*
 * @test
 * @bug 8273553 8253368
 * @summary sun.security.ssl.SSLEngineImpl.closeInbound also has similar error
 *          of JDK-8253368
 * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.3
 * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.2
 * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1.1
 * @run main/othervm SSLSocketSSLEngineCloseInbound TLSv1
 * @run main/othervm SSLSocketSSLEngineCloseInbound TLS
 */

/**
 * A SSLSocket/SSLEngine interop test case.  This is not the way to
 * code SSLEngine-based servers, but works for what we need to do here,
 * which is to make sure that SSLEngine/SSLSockets can talk to each other.
 * SSLEngines can use direct or indirect buffers, and different code
 * is used to get at the buffer contents internally, so we test that here.
 *
 * The test creates one SSLSocket (client) and one SSLEngine (server).
 * The SSLSocket talks to a raw ServerSocket, and the server code
 * does the translation between byte [] and ByteBuffers that the SSLEngine
 * can use.  The "transport" layer consists of a Socket Input/OutputStream
 * and two byte buffers for the SSLEngines:  think of them
 * as directly connected pipes.
 *
 * Again, this is a *very* simple example: real code will be much more
 * involved.  For example, different threading and I/O models could be
 * used, transport mechanisms could close unexpectedly, and so on.
 *
 * When this application runs, notice that several messages
 * (wrap/unwrap) pass before any application data is consumed or
 * produced.  (For more information, please see the SSL/TLS
 * specifications.)  There may several steps for a successful handshake,
 * so it's typical to see the following series of operations:
 *
 *      client          server          message
 *      ======          ======          =======
 *      write()         ...             ClientHello
 *      ...             unwrap()        ClientHello
 *      ...             wrap()          ServerHello/Certificate
 *      read()          ...             ServerHello/Certificate
 *      write()         ...             ClientKeyExchange
 *      write()         ...             ChangeCipherSpec
 *      write()         ...             Finished
 *      ...             unwrap()        ClientKeyExchange
 *      ...             unwrap()        ChangeCipherSpec
 *      ...             unwrap()        Finished
 *      ...             wrap()          ChangeCipherSpec
 *      ...             wrap()          Finished
 *      read()          ...             ChangeCipherSpec
 *      read()          ...             Finished
 */
import javax.net.ssl.*;
import javax.net.ssl.SSLEngineResult.*;
import java.io.*;
import java.net.*;
import java.security.*;
import java.nio.*;

public class SSLSocketSSLEngineCloseInbound {

    /*
     * Enables logging of the SSL/TLS operations.
     */
    private static final boolean logging = true;

    /*
     * Enables the JSSE system debugging system property:
     *
     *     -Djavax.net.debug=all
     *
     * This gives a lot of low-level information about operations underway,
     * including specific handshake messages, and might be best examined
     * after gaining some familiarity with this application.
     */
    private static final boolean debug = false;
    private final SSLContext sslc;
    private SSLEngine serverEngine;     // server-side SSLEngine
    private SSLSocket clientSocket;

    private final byte[] serverMsg =
        "Hi there Client, I'm a Server.".getBytes();
    private final byte[] clientMsg =
        "Hello Server, I'm a Client! Pleased to meet you!".getBytes();

    private ByteBuffer serverOut;       // write side of serverEngine
    private ByteBuffer serverIn;        // read side of serverEngine

    private volatile Exception clientException;
    private volatile Exception serverException;

    /*
     * For data transport, this example uses local ByteBuffers.
     */
    private ByteBuffer cTOs;            // "reliable" transport client->server
    private ByteBuffer sTOc;            // "reliable" transport server->client

    /*
     * The following is to set up the keystores/trust material.
     */
    private static final String pathToStores = "../../../../javax/net/ssl/etc";
    private static final String keyStoreFile = "keystore";
    private static final String trustStoreFile = "truststore";
    private static final String keyFilename =
            System.getProperty("test.src", ".") + "/" + pathToStores
            + "/" + keyStoreFile;
    private static final String trustFilename =
            System.getProperty("test.src", ".") + "/" + pathToStores
            + "/" + trustStoreFile;

    /*
     * Main entry point for this test.
     */
    public static void main(String[] args) throws Exception {
        String protocol = args[0];

        // reset security properties to make sure that the algorithms
        // and keys used in this test are not disabled.
        Security.setProperty("jdk.tls.disabledAlgorithms", "");
        Security.setProperty("jdk.certpath.disabledAlgorithms", "");

        if (debug) {
            System.setProperty("javax.net.debug", "all");
        }

        /*
         * Run the tests with direct and indirect buffers.
         */
        SSLSocketSSLEngineCloseInbound test =
            new SSLSocketSSLEngineCloseInbound(protocol);
        log("-------------------------------------");
        log("Testing " + protocol + " for direct buffers ...");
        test.runTest(true);

        log("---------------------------------------");
        log("Testing " + protocol + " for indirect buffers ...");
        test.runTest(false);

        log("Test Passed.");
    }

    /*
     * Create an initialized SSLContext to use for these tests.
     */
    public SSLSocketSSLEngineCloseInbound(String protocol) throws Exception {

        char[] passphrase = "passphrase".toCharArray();

        KeyStore ks = KeyStore.getInstance(new File(keyFilename), passphrase);
        KeyStore ts = KeyStore.getInstance(new File(trustFilename), passphrase);

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, passphrase);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
        tmf.init(ts);

        SSLContext sslCtx = SSLContext.getInstance(protocol);

        sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        sslc = sslCtx;
    }

    /*
     * Run the test.
     *
     * Sit in a tight loop, with the server engine calling wrap/unwrap
     * regardless of whether data is available or not.  We do this until
     * we get the application data.  Then we shutdown and go to the next one.
     *
     * The main loop handles all the I/O phases of the SSLEngine's
     * lifetime:
     *
     *     initial handshaking
     *     application data transfer
     *     engine closing
     *
     * One could easily separate these phases into separate
     * sections of code.
     */
    private void runTest(boolean direct) throws Exception {
        clientSocket = null;

        // generates the server-side Socket
        try (ServerSocket serverSocket = new ServerSocket()) {
            serverSocket.setReuseAddress(false);
            serverSocket.bind(null);
            int port = serverSocket.getLocalPort();
            log("Port: " + port);
            Thread thread = createClientThread(port);

            createSSLEngine();
            createBuffers(direct);

            // server-side socket that will read
            try (Socket socket = serverSocket.accept()) {
                socket.setSoTimeout(500);

                InputStream is = socket.getInputStream();
                OutputStream os = socket.getOutputStream();

                SSLEngineResult serverResult;   // results from last operation

                /*
                 * Examining the SSLEngineResults could be much more involved,
                 * and may alter the overall flow of the application.
                 *
                 * For example, if we received a BUFFER_OVERFLOW when trying
                 * to write to the output pipe, we could reallocate a larger
                 * pipe, but instead we wait for the peer to drain it.
                 */
                byte[] inbound = new byte[8192];
                byte[] outbound = new byte[8192];

                while (!isEngineClosed(serverEngine)) {
                    int len;

                    // Inbound data
                    log("================");

                    // Try reading Client side, even if it's already closed.
                    try {
                        len = is.read(inbound);
                        if (len > 0) {
                            cTOs.put(inbound, 0, len);
                        }
                    } catch (IOException e) {
                        /*
                         * swallow IO/SocketTimeoutExceptions.  We'll do
                         * the testing/exit after the unwraps.
                         */
                    }

                    cTOs.flip();

                    serverResult = serverEngine.unwrap(cTOs, serverIn);
                    log("server unwrap: ", serverResult);
                    runDelegatedTasks(serverResult, serverEngine);
                    cTOs.compact();

                    // Outbound data
                    log("----");

                    // After we've received  our app bytes, close input side
                    // and see what happens.  Exit the test at the end.
                    if (serverIn.position() != 0) {
                        try {
                            serverEngine.closeInbound();
                            throw new Exception(
                                    "No error shutting down client's input");
                        } catch (SSLException e) {
                            System.out.println(
                                    "Server caught the right Exception");
                        }

                        if (serverEngine.getSession().isValid()) {
                            System.out.println("Server session is still valid");
                        } else {
                            throw new Exception("Server session is not valid");
                        }

                        return;
                    }

                    serverResult = serverEngine.wrap(serverOut, sTOc);
                    log("server wrap: ", serverResult);
                    runDelegatedTasks(serverResult, serverEngine);

                    sTOc.flip();

                    if ((len = sTOc.remaining()) != 0) {
                        sTOc.get(outbound, 0, len);
                        os.write(outbound, 0, len);
                        // Give the other side a chance to process
                    }

                    sTOc.compact();
                }
            } catch (Exception e) {
                serverException = e;
            } finally {
                // Wait for the client to join up with us.
                if (thread != null) {
                    thread.join();
                }
            }
        } finally {
            if (serverException != null) {
                if (clientException != null) {
                    serverException.initCause(clientException);
                }
                throw serverException;
            }
            if (clientException != null) {
                if (serverException != null) {
                    clientException.initCause(serverException);
                }
                throw clientException;
            }
        }
    }

    /*
     * Create a client thread which does simple SSLSocket operations.
     * We'll write and read one data packet.
     */
    private Thread createClientThread(final int port) {

        Thread t = new Thread("ClientThread") {

            @Override
            public void run() {
                // client-side socket
                try (SSLSocket sslSocket = (SSLSocket)sslc.getSocketFactory().
                            createSocket("localhost", port)) {
                    clientSocket = sslSocket;

                    OutputStream os = sslSocket.getOutputStream();

                    // write(byte[]) goes in one shot.
                    os.write(clientMsg);
                    os.flush();

                    try {
                        sslSocket.shutdownInput();
                        throw new Exception(
                                "No error shutting down client's input");
                    } catch (SSLException e) {
                        System.out.println("Client caught the right Exception");
                    }

                    if (sslSocket.getSession().isValid()) {
                        System.out.println("Client session is still valid");
                    } else {
                        throw new Exception("Client's session is not valid");
                    }

                    // Give server a chance to read before we shutdown via
                    // the try-with-resources block.
                    Thread.sleep(2000);
                } catch (Exception e) {
                    clientException = e;
                }
            }
        };
        t.start();
        return t;
    }

    /*
     * Using the SSLContext created during object creation,
     * create/configure the SSLEngines we'll use for this test.
     */
    private void createSSLEngine() {
        /*
         * Configure the serverEngine to act as a server in the SSL/TLS
         * handshake.
         */
        serverEngine = sslc.createSSLEngine();
        serverEngine.setUseClientMode(false);
        serverEngine.getNeedClientAuth();
    }

    /*
     * Create and size the buffers appropriately.
     */
    private void createBuffers(boolean direct) {

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

        /*
         * We'll make the input buffers a bit bigger than the max needed
         * size, so that unwrap()s following a successful data transfer
         * won't generate BUFFER_OVERFLOWS.
         *
         * We'll use a mix of direct and indirect ByteBuffers for
         * tutorial purposes only.  In reality, only use direct
         * ByteBuffers when they give a clear performance enhancement.
         */
        if (direct) {
            serverIn = ByteBuffer.allocateDirect(appBufferMax + 50);
            cTOs = ByteBuffer.allocateDirect(netBufferMax);
            sTOc = ByteBuffer.allocateDirect(netBufferMax);
        } else {
            serverIn = ByteBuffer.allocate(appBufferMax + 50);
            cTOs = ByteBuffer.allocate(netBufferMax);
            sTOc = ByteBuffer.allocate(netBufferMax);
        }

        serverOut = ByteBuffer.wrap(serverMsg);
    }

    /*
     * If the result indicates that we have outstanding tasks to do,
     * go ahead and run them in this thread.
     */
    private static void runDelegatedTasks(SSLEngineResult result,
            SSLEngine engine) throws Exception {

        if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
            Runnable runnable;
            while ((runnable = engine.getDelegatedTask()) != null) {
                log("\trunning delegated task...");
                runnable.run();
            }
            HandshakeStatus hsStatus = engine.getHandshakeStatus();
            if (hsStatus == HandshakeStatus.NEED_TASK) {
                throw new Exception(
                        "handshake shouldn't need additional tasks");
            }
            log("\tnew HandshakeStatus: " + hsStatus);
        }
    }

    private static boolean isEngineClosed(SSLEngine engine) {
        return (engine.isOutboundDone() && engine.isInboundDone());
    }

    /*
     * Logging code
     */
    private static boolean resultOnce = true;

    private static void log(String str, SSLEngineResult result) {
        if (!logging) {
            return;
        }
        if (resultOnce) {
            resultOnce = false;
            log("The format of the SSLEngineResult is: \n"
                    + "\t\"getStatus() / getHandshakeStatus()\" +\n"
                    + "\t\"bytesConsumed() / bytesProduced()\"\n");
        }
        HandshakeStatus hsStatus = result.getHandshakeStatus();
        log(str
                + result.getStatus() + "/" + hsStatus + ", "
                + result.bytesConsumed() + "/" + result.bytesProduced()
                + " bytes");
        if (hsStatus == HandshakeStatus.FINISHED) {
            log("\t...ready for application data");
        }
    }

    private static void log(String str) {
        if (logging) {
            if (debug) {
                System.err.println(str);
            } else {
                System.out.println(str);
            }
        }
    }
}
