/*
 * Copyright (c) 2015, 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.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import jdk.testlibrary.RandomFactory;

/*
 * @test
 * @bug 8050374
 * @key randomness
 * @summary This test validates signature verification
 *          Signature.verify(byte[], int, int). The test uses RandomFactory to
 *          get random set of clear text data to sign. After the signature
 *          generation, the test tries to verify signature with the above API
 *          and passing in different signature offset (0, 33, 66, 99).
 * @library /lib/testlibrary
 * @run main Offsets SUN NONEwithDSA
 * @run main Offsets SUN SHA1withDSA
 * @run main Offsets SUN SHA224withDSA
 * @run main Offsets SUN SHA256withDSA
 */
public class Offsets {

    private final int size;
    private final byte[] cleartext;
    private final PublicKey pubkey;
    private final Signature signature;
    private final byte[] signed;

    private Offsets(Signature signature, PublicKey pubkey, PrivateKey privkey,
            int size, byte[] cleartext) throws InvalidKeyException,
                SignatureException {
        this.pubkey = pubkey;
        this.signature = signature;
        this.size = size;
        this.cleartext = cleartext;

        signature.initSign(privkey);
        signature.update(cleartext, 0, size);
        signed = signature.sign();
    }

    int getDataSize() {
        return size;
    }

    int getSignatureLength() {
        return signed.length;
    }

    byte[] shiftSignData(int offset) {
        byte[] testSignData = new byte[offset + signed.length];
        System.arraycopy(signed, 0, testSignData, offset,
                signed.length);
        return testSignData;
    }

    boolean verifySignature(byte[] sigData, int sigOffset, int sigLength,
            int updateOffset, int updateLength)
                throws InvalidKeyException, SignatureException {
        signature.initVerify(pubkey);
        signature.update(cleartext, updateOffset, updateLength);
        return signature.verify(sigData, sigOffset, sigLength);
    }

    static Offsets init(String provider, String algorithm)
            throws NoSuchAlgorithmException, NoSuchProviderException,
            InvalidKeyException, SignatureException {
        // fill the cleartext data with random bytes
        byte[] cleartext = new byte[100];
        RandomFactory.getRandom().nextBytes(cleartext);

        // NONEwith requires input to be of 20 bytes
        int size = algorithm.contains("NONEwith") ? 20 : 100;

        // create signature instance
        Signature signature = Signature.getInstance(algorithm, provider);

        String keyAlgo;
        if (algorithm.contains("RSA")) {
            keyAlgo = "RSA";
        } else if (algorithm.contains("ECDSA")) {
            keyAlgo = "EC";
        } else if (algorithm.contains("DSA")) {
            keyAlgo = "DSA";
        } else {
            throw new RuntimeException("Test doesn't support this signature "
                    + "algorithm: " + algorithm);
        }

        KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgo, provider);
        KeyPair kp = kpg.generateKeyPair();
        PublicKey pubkey = kp.getPublic();
        PrivateKey privkey = kp.getPrivate();

        return new Offsets(signature, pubkey, privkey, size, cleartext);
    }

    public static void main(String[] args) throws NoSuchAlgorithmException,
            InvalidKeyException, SignatureException {
        if (args.length < 2) {
            throw new RuntimeException("Wrong parameters");
        }

        boolean result = true;
        try {
            Offsets test = init(args[0], args[1]);

            // We are trying 3 different offsets, data size has nothing to do
            // with signature length
            for (int chunk = 3; chunk > 0; chunk--) {
                int signOffset = test.getDataSize() / chunk;

                System.out.println("Running test with offset " + signOffset);
                byte[] signData = test.shiftSignData(signOffset);

                boolean success = test.verifySignature(signData, signOffset,
                        test.getSignatureLength(), 0, test.getDataSize());

                if (success) {
                    System.out.println("Successfully verified with offset "
                            + signOffset);
                } else {
                    System.out.println("Verification failed with offset "
                            + signOffset);
                    result = false;
                }
            }

            // save signature to offset 0
            byte[] signData = test.shiftSignData(0);

            // Negative tests

            // Test signature offset 0.
            // Wrong test data will be passed to update,
            // so signature verification should fail.
            for (int chunk = 3; chunk > 0; chunk--) {
                int dataOffset = (test.getDataSize() - 1) / chunk;
                boolean success;
                try {
                    success = test.verifySignature(signData, 0,
                            test.getSignatureLength(), dataOffset,
                            (test.getDataSize() - dataOffset));
                } catch (SignatureException e) {
                    // Since we are trying different data size, it can throw
                    // SignatureException
                    success = false;
                }

                if (!success) {
                    System.out.println("Signature verification failed "
                            + "as expected, with data offset " + dataOffset
                            + " and length "
                            + (test.getDataSize() - dataOffset));
                } else {
                    System.out.println("Signature verification "
                            + "should not succeed, with data offset "
                            + dataOffset + " and length "
                            + (test.getDataSize() - dataOffset));
                    result = false;
                }
            }

            // Tests with manipulating offset and length
            result &= Offsets.checkFailure(test, signData, -1,
                    test.getSignatureLength());

            result &= Offsets.checkFailure(test, signData, 0,
                    test.getSignatureLength() - 1);

            result &= Offsets.checkFailure(test, signData,
                    test.getSignatureLength() + 1, test.getSignatureLength());

            result &= Offsets.checkFailure(test, signData, 0,
                    test.getSignatureLength() + 1);

            result &= Offsets.checkFailure(test, signData, 0, 0);

            result &= Offsets.checkFailure(test, signData, 0, -1);

            result &= Offsets.checkFailure(test, signData,
                    2147483646, test.getSignatureLength());

            result &= Offsets.checkFailure(test, null, 0,
                    test.getSignatureLength());
        } catch (NoSuchProviderException nspe) {
            System.out.println("No such provider: " + nspe);
        }

        if (!result) {
            throw new RuntimeException("Some test cases failed");
        }
    }

    static boolean checkFailure(Offsets test, byte[] signData, int offset,
            int length) {
        boolean success;
        try {
            success = test.verifySignature(signData, offset, length, 0,
                    test.getDataSize());
        } catch (IllegalArgumentException | SignatureException e) {
            System.out.println("Expected exception: " + e);
            success = false;
        } catch (InvalidKeyException e) {
            System.out.println("Unexpected exception: " + e);
            return false;
        }

        if (!success) {
            System.out.println("Signature verification failed as expected, "
                    + "with signature offset " + offset + " and length "
                    + length);
            return true;
        } else {
            System.out.println("Signature verification should not succeed, "
                    + "with signature offset " + offset + " and length "
                    + length);
            return false;
        }
    }

}
