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

import java.security.*;
import java.security.spec.*;
import java.math.*;
import java.util.*;

/*
 * @test
 * @bug 8147502
 * @summary Test that digests are properly truncated before the signature
 *     is applied. The digest should be truncated to the bit length of the
 *     group order.
 * @library /test/lib
 * @build jdk.test.lib.Convert
 * @run main/othervm SignatureDigestTruncate
 */
public class SignatureDigestTruncate {

    /*
     * A SecureRandom that produces nextBytes in a way that causes the nonce
     * to be set to the value supplied to the constructor. This class
     * is specific to the way that the native ECDSA implementation in
     * SunEC produces nonces from random input. It may not work for all
     * test cases, and it will need to be updated when the behavior of
     * SunEC changes.
     */
    private static class FixedRandom extends SecureRandom {

        private final byte[] val;

        public FixedRandom(byte[] val) {
            // SunEC adds one to the value returned, so subtract one here in
            // order to get back to the correct value.
            BigInteger biVal = new BigInteger(1, val);
            biVal = biVal.subtract(BigInteger.ONE);
            byte[] temp = biVal.toByteArray();
            this.val = new byte[val.length];
            int inStartPos = Math.max(0, temp.length - val.length);
            int outStartPos = Math.max(0, val.length - temp.length);
            System.arraycopy(temp, inStartPos, this.val, outStartPos,
                temp.length - inStartPos);
        }

        @Override
        public void nextBytes(byte[] bytes) {
            // SunEC samples (n + 1) * 2 bytes, but only n*2 bytes are used by
            // the native implementation. So the value must be offset slightly.
            Arrays.fill(bytes, (byte) 0);
            int copyLength = Math.min(val.length, bytes.length - 2);
            System.arraycopy(val, 0, bytes, bytes.length - copyLength - 2,
                copyLength);
        }
    }

    private static void assertEquals(byte[] expected, byte[] actual,
            String name) {
        if (!Arrays.equals(actual, expected)) {
            System.out.println("expect: " + HexFormat.of().withUpperCase().formatHex(expected));
            System.out.println("actual: " + HexFormat.of().withUpperCase().formatHex(actual));
            throw new RuntimeException("Incorrect " + name + " value");
        }
    }

    private static void runTest(String alg, String curveName,
        String privateKeyStr, String msgStr, String kStr, String sigStr)
        throws Exception {

        System.out.println("Testing " + alg + " with " + curveName);

        HexFormat hex = HexFormat.of();
        byte[] privateKey = hex.parseHex(privateKeyStr);
        byte[] msg = hex.parseHex(msgStr);
        byte[] k = hex.parseHex(kStr);
        byte[] expectedSig = hex.parseHex(sigStr);

        AlgorithmParameters params =
            AlgorithmParameters.getInstance("EC",
                    System.getProperty("test.provider.name", "SunEC"));
        params.init(new ECGenParameterSpec(curveName));
        ECParameterSpec ecParams =
            params.getParameterSpec(ECParameterSpec.class);

        KeyFactory kf = KeyFactory.getInstance("EC",
                            System.getProperty("test.provider.name", "SunEC"));
        BigInteger s = new BigInteger(1, privateKey);
        ECPrivateKeySpec privKeySpec = new ECPrivateKeySpec(s, ecParams);
        PrivateKey privKey = kf.generatePrivate(privKeySpec);

        Signature sig = Signature.getInstance(alg,
                            System.getProperty("test.provider.name", "SunEC"));
        sig.initSign(privKey, new FixedRandom(k));
        sig.update(msg);
        byte[] computedSig = sig.sign();
        assertEquals(expectedSig, computedSig, "signature");
    }

    public static void main(String[] args) throws Exception {
        runTest("SHA384withECDSAinP1363Format", "secp256r1",
            "abcdef10234567", "010203040506070809",
            "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d" +
                "1e1f20212223",
            "d83534beccde787f9a4c6b0408337d9b9ca2e0a0259228526c15cc17a1d6" +
                "4da6b34bf21b3bc4488c591d8ac9c33d93c7c6137e2ab4c503a42da7" +
                "2fe0b6dda4c4");
    }
}
