/*
 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
 * Copyright (C) 2021, 2024, Tencent. 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 8263188
 * @summary If TLS the server and client has no common signature algorithms,
 *     the connection should fail fast with "No supported signature algorithm".
 *     This test only covers TLS 1.2.
 *
 * @library /test/lib
 *          /javax/net/ssl/templates
 *
 * @run main/othervm
 *     -Djdk.tls.server.SignatureSchemes=ecdsa_secp384r1_sha384
 *     -Djdk.tls.client.SignatureSchemes=ecdsa_secp256r1_sha256,ecdsa_secp384r1_sha384
 *     -Dtest.clientAuth=false
 *     -Dtest.expectFail=false
 *     SigAlgosExtTestWithTLS12
 * @run main/othervm
 *     -Djdk.tls.server.SignatureSchemes=ecdsa_secp384r1_sha384
 *     -Djdk.tls.client.SignatureSchemes=ecdsa_secp256r1_sha256
 *     -Dtest.clientAuth=false
 *     -Dtest.expectFail=true
 *     SigAlgosExtTestWithTLS12
 * @run main/othervm
 *     -Djdk.tls.server.SignatureSchemes=ecdsa_secp256r1_sha256
 *     -Djdk.tls.client.SignatureSchemes=ecdsa_secp256r1_sha256
 *     -Dtest.clientAuth=true
 *     -Dtest.expectFail=true
 *     SigAlgosExtTestWithTLS12
 */

import javax.net.ssl.*;
import java.nio.ByteBuffer;
import java.util.*;

public class SigAlgosExtTestWithTLS12 extends SSLEngineTemplate {

    private static final boolean CLIENT_AUTH
            = Boolean.getBoolean("test.clientAuth");
    private static final boolean EXPECT_FAIL
            = Boolean.getBoolean("test.expectFail");

    private static final int TLS_HS_CERT_REQ = 13;

    public SigAlgosExtTestWithTLS12() throws Exception {
        super();
    }

    /*
     * Create an instance of KeyManager for client use.
     */
    @Override
    protected KeyManager createClientKeyManager() throws Exception {
        return createKeyManager(
                new Cert[]{Cert.EE_ECDSA_SECP256R1, Cert.EE_ECDSA_SECP384R1},
                getClientContextParameters());
    }

    @Override
    public TrustManager createClientTrustManager() throws Exception {
        return createTrustManager(
                new Cert[]{Cert.CA_ECDSA_SECP256R1, Cert.CA_ECDSA_SECP384R1},
                getServerContextParameters());
    }

    @Override
    public KeyManager createServerKeyManager() throws Exception {
        return createKeyManager(
                new Cert[]{Cert.EE_ECDSA_SECP256R1, Cert.EE_ECDSA_SECP384R1},
                getServerContextParameters());
    }

    @Override
    public TrustManager createServerTrustManager() throws Exception {
        return createTrustManager(
                new Cert[]{Cert.CA_ECDSA_SECP256R1, Cert.CA_ECDSA_SECP384R1},
                getServerContextParameters());
    }

    @Override
    protected SSLEngine configureServerEngine(SSLEngine serverEngine) {
        serverEngine.setUseClientMode(false);
        serverEngine.setNeedClientAuth(CLIENT_AUTH);
        return serverEngine;
    }

    @Override
    protected SSLEngine configureClientEngine(SSLEngine clientEngine) {
        clientEngine.setUseClientMode(true);
        clientEngine.setEnabledProtocols(new String[] { "TLSv1.2" });
        return clientEngine;
    }

    public static void main(String[] args) throws Exception {
        System.setProperty("javax.net.debug", "ssl:handshake");

        try {
            new SigAlgosExtTestWithTLS12().run();
            if (EXPECT_FAIL) {
                throw new RuntimeException(
                        "Expected SSLHandshakeException wasn't thrown");
            }
        } catch (SSLHandshakeException e) {
            if (EXPECT_FAIL && e.getMessage().endsWith(
                    "No supported signature algorithm")) {
                System.out.println("Expected SSLHandshakeException");
            } else {
                throw e;
            }
        }
    }

    private void run() throws Exception {
        boolean dataDone = false;
        while (isOpen(clientEngine) || isOpen(serverEngine)) {
            clientEngine.wrap(clientOut, cTOs);
            cTOs.flip();

            // Consume the ClientHello and get the server flight of handshake
            // messages.  We expect that it will be one TLS record containing
            // multiple handshake messages, one of which is a CertificateRequest
            // when the client authentication is required.
            serverEngine.unwrap(cTOs, serverIn);
            runDelegatedTasks(serverEngine);

            // Wrap the server flight
            serverEngine.wrap(serverOut, sTOc);
            sTOc.flip();

            if (CLIENT_AUTH && EXPECT_FAIL) {
                twistCertReqMsg(sTOc);
            }

            clientEngine.unwrap(sTOc, clientIn);
            runDelegatedTasks(clientEngine);

            serverEngine.unwrap(cTOs, serverIn);
            runDelegatedTasks(serverEngine);

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

            if (!dataDone && (clientOut.limit() == serverIn.position()) &&
                    (serverOut.limit() == clientIn.position())) {
                checkTransfer(serverOut, clientIn);
                checkTransfer(clientOut, serverIn);

                clientEngine.closeOutbound();
                dataDone = true;
                serverEngine.closeOutbound();
            }
        }
    }

    /**
     * Twists signature schemes in CertificateRequest message for negative
     * client authentication cases.
     *
     * @param tlsRecord a ByteBuffer containing a TLS record.  It is assumed
     *      that the position of the ByteBuffer is on the first byte of the TLS
     *      record header.
     *
     * @throws SSLException if the incoming ByteBuffer does not contain a
     *      well-formed TLS message.
     */
    private static void twistCertReqMsg(
            ByteBuffer tlsRecord) throws SSLException {
        Objects.requireNonNull(tlsRecord);
        tlsRecord.mark();

        // Process the TLS record header
        int type = Byte.toUnsignedInt(tlsRecord.get());
        int ver_major = Byte.toUnsignedInt(tlsRecord.get());
        int ver_minor = Byte.toUnsignedInt(tlsRecord.get());
        int recLen = Short.toUnsignedInt(tlsRecord.getShort());

        // Simple sanity checks
        if (type != 22) {
            throw new SSLException("Not a handshake: Type = " + type);
        } else if (recLen > tlsRecord.remaining()) {
            throw new SSLException("Incomplete record in buffer: " +
                    "Record length = " + recLen + ", Remaining = " +
                    tlsRecord.remaining());
        }

        while (tlsRecord.hasRemaining()) {
            // Grab the handshake message header.
            int msgHdr = tlsRecord.getInt();
            int msgType = (msgHdr >> 24) & 0x000000FF;
            int msgLen = msgHdr & 0x00FFFFFF;

            if (msgType == TLS_HS_CERT_REQ) {
                // Slice the buffer such that it contains the entire
                // handshake message (less the handshake header).
                int bufPos = tlsRecord.position();
                ByteBuffer buf = tlsRecord.slice(bufPos, msgLen);

                // Replace the signature scheme with an unknown value
                twistSigSchemesCertReq(buf, (short) 0x0000);
                byte[] bufBytes = new byte[buf.limit()];
                buf.get(bufBytes);
                tlsRecord.put(bufPos, bufBytes);

                break;
            } else {
                // Skip to the next handshake message, if there is one
                tlsRecord.position(tlsRecord.position() + msgLen);
            }
        }

        tlsRecord.reset();
    }

    /**
     * Replace the signature schemes in CertificateRequest message with an
     * alternative value.  It is assumed that the provided ByteBuffer has its
     * position set at the first byte of the CertificateRequest message body
     * (AFTER the handshake header) and contains the entire CR message.  Upon
     * successful completion of this method the ByteBuffer will have its
     * position reset to the initial offset in the buffer.
     * If an exception is thrown the position at the time of the exception
     * will be preserved.
     *
     * @param data the ByteBuffer containing the CertificateRequest bytes
     * @param altSigScheme an alternative signature scheme
     */
    private static void twistSigSchemesCertReq(ByteBuffer data,
                                               Short altSigScheme) {
        Objects.requireNonNull(data);
        data.mark();

        // Jump past the certificate types
        int certTypeLen = Byte.toUnsignedInt(data.get());
        if (certTypeLen != 0) {
            data.position(data.position() + certTypeLen);
        }

        int sigSchemeLen = Short.toUnsignedInt(data.getShort());
        for (int ssOff = 0; ssOff < sigSchemeLen; ssOff += 2) {
            System.err.println(
                    "Use alternative signature scheme: " + altSigScheme);
            data.putShort(data.position(), altSigScheme);
        }

        data.reset();
    }
}
