/*
 * Copyright (c) 2018, 2025, 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.
 */

/*
 * @test
 * @bug 8164879 8300285
 * @library ../../
 * @library /test/lib
 * @modules java.base/sun.security.util
 * @summary Verify AEAD TLS cipher suite limits set in the jdk.tls.keyLimits
 * property
 * @run main SSLSocketKeyLimit 0 server TLS_AES_256_GCM_SHA384
 *      AES/GCM/NoPadding keyupdate 1000000
 * @run main SSLSocketKeyLimit 0 client TLS_AES_256_GCM_SHA384
 *      AES/GCM/NoPadding keyupdate 1000000
 * @run main SSLSocketKeyLimit 1 client TLS_AES_256_GCM_SHA384
 *      AES/GCM/NoPadding keyupdate 2^22
 * @run main SSLSocketKeyLimit 0 server TLS_CHACHA20_POLY1305_SHA256
 *      AES/GCM/NoPadding keyupdate 1000000, ChaCha20-Poly1305 KeyUpdate 1000000
 * @run main SSLSocketKeyLimit 0 client TLS_CHACHA20_POLY1305_SHA256
 *      AES/GCM/NoPadding keyupdate 1000000, ChaCha20-Poly1305 KeyUpdate 1000000
 * @run main SSLSocketKeyLimit 1 client TLS_CHACHA20_POLY1305_SHA256
 *      AES/GCM/NoPadding keyupdate 2^22, ChaCha20-Poly1305 KeyUpdate 2^22
 */

 /**
  * Verify AES/GCM's limits set in the jdk.tls.keyLimits property
  * start a new handshake sequence to renegotiate the symmetric key with an
  * SSLSocket connection.  This test verifies the handshake method was called
  * via debugging info.  It does not verify the renegotiation was successful
  * as that is very hard.
  */

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Arrays;

import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.Utils;
import jdk.test.lib.hexdump.HexPrinter;

public class SSLSocketKeyLimit {
    SSLSocket socket;
    private InputStream in;
    private OutputStream out;

    static boolean serverReady = false;
    static int serverPort = 0;

    static String pathToStores = "../../../../javax/net/ssl/etc/";
    static String keyStoreFile = "keystore";
    static String passwd = "passphrase";
    static int dataLen = 10240;
    static byte[] data  = new byte[dataLen];
    static boolean serverwrite = true;
    int totalDataLen = 0;
    static boolean done = false;

    SSLSocketKeyLimit() {
    }

    SSLContext initContext() throws Exception {
        SSLContext sc = SSLContext.getInstance("TLSv1.3");
        KeyStore ks = KeyStore.getInstance(
                new File(System.getProperty("javax.net.ssl.keyStore")),
                passwd.toCharArray());
        KeyManagerFactory kmf =
                KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, passwd.toCharArray());
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
        return sc;
    }

    /**
     * args should have three values:  server|client, cipher suite, <limit size>
     * Prepending 'p' is for internal use only.
     */
    public static void main(String args[]) throws Exception {
        if (args[0].compareTo("p") != 0) {

            boolean expectedFail = (Integer.parseInt(args[0]) == 1);
            if (expectedFail) {
                System.out.println("Test expected to not find updated msg");
            }
            //Write security property file to overwrite default
            File f = new File("keyusage."+ System.nanoTime());
            PrintWriter p = new PrintWriter(f);
            p.write("jdk.tls.keyLimits=");
            for (int i = 3; i < args.length; i++) {
                p.write(" "+ args[i]);
            }
            p.close();
            System.out.println("Keyusage path = " + f.getAbsolutePath());
            System.setProperty("test.java.opts", System.getProperty("test.java.opts") +
                    " -Dtest.src=" + System.getProperty("test.src") +
                            " -Dtest.jdk=" + System.getProperty("test.jdk") +
                            " -Djavax.net.debug=ssl,handshake" +
                            " -Djava.security.properties=" + f.getName());

            System.out.println("test.java.opts: " +
                    System.getProperty("test.java.opts"));

            ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
                    Utils.addTestJavaOpts("SSLSocketKeyLimit", "p", args[1],
                            args[2]));

            OutputAnalyzer output = ProcessTools.executeProcess(pb);
            try {
                output.shouldContain(String.format(
                        "\"cipher suite\"        : \"%s", args[2]));
                if (expectedFail) {
                    output.shouldNotContain("KeyUpdate: write key updated");
                    output.shouldNotContain("KeyUpdate: read key updated");
                } else {
                    output.shouldContain("trigger key update");
                    output.shouldContain("KeyUpdate: write key updated");
                    output.shouldContain("KeyUpdate: read key updated");
                }
            } catch (Exception e) {
                throw e;
            } finally {
                System.out.println("-- BEGIN Stdout:");
                System.out.println(output.getStdout());
                System.out.println("-- END Stdout");
                System.out.println("-- BEGIN Stderr:");
                System.out.println(output.getStderr());
                System.out.println("-- END Stderr");
            }
            return;
        }

        if (args.length > 0 && args[1].compareToIgnoreCase("client") == 0) {
            serverwrite = false;
        }

        String keyFilename =
            System.getProperty("test.src", "./") + "/" + pathToStores +
                "/" + keyStoreFile;

        System.setProperty("javax.net.ssl.keyStore", keyFilename);
        System.setProperty("javax.net.ssl.keyStorePassword", passwd);

        Arrays.fill(data, (byte)0x0A);
        Thread ts = new Thread(new Server(args[2]));

        ts.start();
        while (!serverReady) {
            Thread.sleep(100);
        }
        new Client().run();
        ts.join(10000);  // 10sec
        System.exit(0);
    }

    void write(SSLSocket s) throws Exception {
        int i = 0;
        in = s.getInputStream();
        out = s.getOutputStream();
        while (i++ < 150) {
            out.write(data, 0, dataLen);
            System.out.print("W");
            in.readNBytes(1);
            System.out.print("R");
        }
        out.write(0x0D);
        out.flush();

        // Let read side all the data
        while (!done) {
            Thread.sleep(100);
        }
        out.close();
        in.close();
    }


    void read(SSLSocket s) throws Exception {
        byte[] buf = new byte[dataLen];
        int len;
        byte i = 0;
        try {
            System.out.println("Server: connected " +
                    s.getSession().getCipherSuite());
            in = s.getInputStream();
            out = s.getOutputStream();
            while (true) {
                len = in.read(buf, 0, dataLen);
                System.out.print("r");
                out.write(i++);
                System.out.print("w");
                for (byte b: buf) {
                    if (b == 0x0A || b == 0x0D) {
                        continue;
                    }
                    System.out.println("\nData invalid: " +
                            HexPrinter.minimal().toString(buf));
                    break;
                }

                if (len > 0 && buf[len-1] == 0x0D) {
                    System.out.println("got end byte");
                    break;
                }
                totalDataLen += len;
            }
        } catch (Exception e) {
            System.out.println("\n"  + e.getMessage());
            e.printStackTrace();
        } finally {
            // Tell write side that we are done reading
            out.close();
            in.close();
            done = true;
        }
        System.out.println("\nTotalDataLen = " + totalDataLen);
    }

    static class Server extends SSLSocketKeyLimit implements Runnable {
        private SSLServerSocketFactory ssf;
        private SSLServerSocket ss;
        Server(String cipherSuite) {
            super();
            try {
                ssf = initContext().getServerSocketFactory();
                ss = (SSLServerSocket) ssf.createServerSocket(serverPort);
                if (cipherSuite != null && cipherSuite.length() > 0) {
                    ss.setEnabledCipherSuites(new String[] { cipherSuite });
                }
                serverPort = ss.getLocalPort();
            } catch (Exception e) {
                System.out.println("server: " + e.getMessage());
                e.printStackTrace();
            }
        }

        public void run() {
            try {
                serverReady = true;
                System.out.println("Server waiting... port: " + serverPort);
                socket = (SSLSocket) ss.accept();
                if (serverwrite) {
                    write(socket);
                } else {
                    read(socket);
                }

                socket.close();
            } catch (Exception e) {
                System.out.println("server: " + e.getMessage());
                e.printStackTrace();
            }
            System.out.println("Server closed");
        }
    }


    static class Client extends SSLSocketKeyLimit implements Runnable {
        private SSLSocketFactory sf;

        Client() {
            super();
        }

        public void run() {
            try {
                sf = initContext().getSocketFactory();
                System.out.println("Client: connecting... port: " + serverPort);
                socket = (SSLSocket)sf.createSocket("localhost", serverPort);
                System.out.println("Client: connected." + socket.getSession().getCipherSuite());

                // Opposite of what the server does
                if (!serverwrite) {
                    write(socket);
                } else {
                    read(socket);
                }

            } catch (Exception e) {
                System.err.println("client: " + e.getMessage());
                e.printStackTrace();
            }
        }
    }
}
