/*
 * Copyright (c) 2003, 2012, 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 4853305 4865198 4888410 4963723
 * @summary Verify that the RSA KeyPairGenerator works
 * @author Andreas Sterbenz
 */

import java.io.*;
import java.util.*;
import java.math.BigInteger;

import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;

public class TestKeyPairGenerator {

    private static Provider provider;

    private static byte[] data;

    private static void testSignature(String algorithm, PrivateKey privateKey, PublicKey publicKey) throws Exception {
        System.out.println("Testing " + algorithm + "...");
        Signature s = Signature.getInstance(algorithm, provider);
        s.initSign(privateKey);
        s.update(data);
        byte[] sig = s.sign();
        s.initVerify(publicKey);
        s.update(data);
        boolean result = s.verify(sig);
        if (result == false) {
            throw new Exception("Verification failed");
        }
    }

    private static void test(PrivateKey privateKey, PublicKey publicKey) throws Exception {
        testSignature("MD2withRSA", privateKey, publicKey);
        testSignature("MD5withRSA", privateKey, publicKey);
        testSignature("SHA1withRSA", privateKey, publicKey);
        testSignature("SHA224withRSA", privateKey, publicKey);
        testSignature("SHA256withRSA", privateKey, publicKey);
        RSAPublicKey rsaKey = (RSAPublicKey)publicKey;
        if (rsaKey.getModulus().bitLength() > 512) {
            // for SHA384 and SHA512 the data is too long for 512 bit keys
            testSignature("SHA384withRSA", privateKey, publicKey);
            testSignature("SHA512withRSA", privateKey, publicKey);
        }
    }

    // regression test for 4865198
    private static void testInvalidSignature(KeyPair kp1, KeyPair kp2) throws Exception {
        System.out.println("Testing signature with incorrect key...");
        Signature sig = Signature.getInstance("MD5withRSA", provider);
        sig.initSign(kp1.getPrivate());
        byte[] data = new byte[100];
        sig.update(data);
        byte[] signature = sig.sign();
        sig.initVerify(kp1.getPublic());
        sig.update(data);
        if (sig.verify(signature) == false) {
            throw new Exception("verification failed");
        }
        sig.initVerify(kp2.getPublic());
        sig.update(data);
        // verify needs to return false and not throw an Exception
        try {
            if (sig.verify(signature)) {
                throw new Exception("verification unexpectedly succeeded");
            }
        } catch (SignatureException se) {
            // Yet another kind of failure, OK.
        }
    }

    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        provider = Security.getProvider("SunRsaSign");
        data = new byte[2048];
        // keypair generation is very slow, test only a few short keys
        int[] keyLengths = {512, 512, 1024};
        BigInteger[] pubExps = {null, BigInteger.valueOf(3), null};
        KeyPair[] keyPairs = new KeyPair[3];
        new Random().nextBytes(data);
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", provider);
        for (int i = 0; i < keyLengths.length; i++) {
            int len = keyLengths[i];
            BigInteger exp = pubExps[i];
            System.out.println("Generating " + len + " bit keypair...");
            if (exp == null) {
                kpg.initialize(len);
            } else {
                kpg.initialize(new RSAKeyGenParameterSpec(len, exp));
            }
            KeyPair kp = kpg.generateKeyPair();
            keyPairs[i] = kp;
            RSAPublicKey publicKey = (RSAPublicKey)kp.getPublic();
            System.out.println(publicKey);
            RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey)kp.getPrivate();
            if (publicKey.getModulus().equals(privateKey.getModulus()) == false) {
                throw new Exception("Moduli do not match");
            }
            if (publicKey.getPublicExponent().equals(privateKey.getPublicExponent()) == false) {
                throw new Exception("Exponents do not match");
            }
            int keyLen = publicKey.getModulus().bitLength();
            if ((keyLen > len) || (keyLen < len - 1)) {
                throw new Exception("Incorrect key length: " + keyLen);
            }
            if (exp != null) {
                if (exp.equals(publicKey.getPublicExponent()) == false) {
                    throw new Exception("Incorrect exponent");
                }
            }
            test(privateKey, publicKey);
        }
        testInvalidSignature(keyPairs[0], keyPairs[1]);
        testInvalidSignature(keyPairs[0], keyPairs[2]);
        testInvalidSignature(keyPairs[2], keyPairs[0]);
        long stop = System.currentTimeMillis();
        System.out.println("All tests passed (" + (stop - start) + " ms).");
    }
}
