8044199: Tests for RSA keys and key specifications
Summary: added various tests for SunRsaSign provider
Reviewed-by: valeriep
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/rsa/KeySizeTest.java Wed Sep 09 21:57:38 2015 +0000
@@ -0,0 +1,130 @@
+/*
+ * 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.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+
+/**
+ * @test
+ * @bug 8044199
+ * @summary test if the private and public key size are the same as what is set
+ * through KeyPairGenerator.
+ * @run main KeySizeTest 512 10
+ * @run main KeySizeTest 768 10
+ * @run main KeySizeTest 1024 10
+ * @run main KeySizeTest 2048 5
+ * @run main KeySizeTest 4096 1
+ */
+public class KeySizeTest {
+
+ /**
+ * ALGORITHM name, fixed as RSA.
+ */
+ private static final String KEYALG = "RSA";
+
+ /**
+ * JDK default RSA Provider.
+ */
+ private static final String PROVIDER_NAME = "SunRsaSign";
+
+ public static void main(String[] args) throws Exception {
+ int iKeyPairSize = Integer.parseInt(args[0]);
+ int maxLoopCnt = Integer.parseInt(args[1]);
+
+ int failCount = 0;
+ KeyPairGenerator keyPairGen
+ = KeyPairGenerator.getInstance(KEYALG, PROVIDER_NAME);
+ keyPairGen.initialize(iKeyPairSize);
+ // Generate RSA keypair
+ KeyPair keyPair = keyPairGen.generateKeyPair();
+
+ // Get priavte and public keys
+ PrivateKey privateKey = keyPair.getPrivate();
+ PublicKey publicKey = keyPair.getPublic();
+ try {
+ if (!sizeTest(keyPair)) {
+ failCount++;
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace(System.err);
+ failCount++;
+ }
+
+ for (int iCnt = 0; iCnt < maxLoopCnt; iCnt++) {
+
+ // Get keysize (modulus) of keys
+ KeyFactory keyFact = KeyFactory.getInstance(KEYALG, PROVIDER_NAME);
+
+ // Comparing binary length.
+ RSAPrivateKeySpec privateKeySpec
+ = (RSAPrivateKeySpec) keyFact.getKeySpec(privateKey,
+ RSAPrivateKeySpec.class);
+ int iPrivateKeySize = privateKeySpec.getModulus().bitLength();
+
+ RSAPublicKeySpec publicKeySpec
+ = (RSAPublicKeySpec) keyFact.getKeySpec(publicKey,
+ RSAPublicKeySpec.class);
+ int iPublicKeySize = publicKeySpec.getModulus().bitLength();
+
+ if ((iKeyPairSize != iPublicKeySize) || (iKeyPairSize != iPrivateKeySize)) {
+ System.err.println("iKeyPairSize : " + iKeyPairSize);
+ System.err.println("Generated a " + iPrivateKeySize
+ + " bit RSA private key");
+ System.err.println("Generated a " + iPublicKeySize
+ + " bit RSA public key");
+ failCount++;
+ }
+ }
+
+ if (failCount > 0) {
+ throw new RuntimeException("There are " + failCount + " tests failed.");
+ }
+ }
+
+ /**
+ * @param kpair test key pair.
+ * @return true if test passed. false if test failed.
+ */
+ private static boolean sizeTest(KeyPair kpair) {
+ RSAPrivateKey priv = (RSAPrivateKey) kpair.getPrivate();
+ RSAPublicKey pub = (RSAPublicKey) kpair.getPublic();
+
+ // test the getModulus method
+ if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) {
+ if (!priv.getModulus().equals(pub.getModulus())) {
+ System.err.println("priv.getModulus() = " + priv.getModulus());
+ System.err.println("pub.getModulus() = " + pub.getModulus());
+ return false;
+ }
+ }
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/rsa/PrivateKeyEqualityTest.java Wed Sep 09 21:57:38 2015 +0000
@@ -0,0 +1,108 @@
+/*
+ * 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.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.interfaces.RSAPrivateCrtKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPrivateCrtKeySpec;
+
+/**
+ * @test
+ * @bug 8044199 4666485
+ * @summary Equality checking for RSAPrivateKey by SunRsaSign provider.
+ */
+public class PrivateKeyEqualityTest {
+ /**
+ * ALGORITHM name, fixed as RSA.
+ */
+ private static final String KEYALG = "RSA";
+
+ /**
+ * JDK default RSA Provider.
+ */
+ private static final String PROVIDER_NAME = "SunRsaSign";
+
+ public static void main(String[] args) throws NoSuchAlgorithmException,
+ NoSuchProviderException, InvalidKeySpecException {
+ // Generate the first key.
+ KeyPairGenerator generator
+ = KeyPairGenerator.getInstance(KEYALG, PROVIDER_NAME);
+ KeyPair keyPair = generator.generateKeyPair();
+ RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
+ if (!(rsaPrivateKey instanceof RSAPrivateCrtKey)) {
+ System.err.println("rsaPrivateKey class : " + rsaPrivateKey.getClass().getName());
+ throw new RuntimeException("rsaPrivateKey is not a RSAPrivateCrtKey instance");
+ }
+
+ // Generate the second key.
+ KeyFactory factory = KeyFactory.getInstance(KEYALG, PROVIDER_NAME);
+ RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(
+ rsaPrivateKey.getModulus(), rsaPrivateKey.getPrivateExponent());
+ RSAPrivateKey rsaPrivateKey2 = (RSAPrivateKey) factory.generatePrivate(
+ rsaPrivateKeySpec);
+
+ // Generate the third key.
+ PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(
+ rsaPrivateKey.getEncoded());
+ RSAPrivateKey rsaPrivateKey3 = (RSAPrivateKey) factory.generatePrivate(
+ encodedKeySpec);
+
+ // Check for equality.
+ if (rsaPrivateKey.equals(rsaPrivateKey2)) {
+ throw new RuntimeException("rsaPrivateKey should not equal to rsaPrivateKey2");
+ }
+ if (!rsaPrivateKey3.equals(rsaPrivateKey)) {
+ throw new RuntimeException("rsaPrivateKey3 should equal to rsaPrivateKey");
+ }
+ if (rsaPrivateKey3.equals(rsaPrivateKey2)) {
+ throw new RuntimeException("rsaPrivateKey3 should not equal to rsaPrivateKey2");
+ }
+ if (rsaPrivateKey2.equals(rsaPrivateKey3)) {
+ throw new RuntimeException("rsaPrivateKey2 should not equal to rsaPrivateKey3");
+ }
+
+ // Generate the fourth key.
+ RSAPrivateCrtKey rsaPrivateCrtKey = (RSAPrivateCrtKey)rsaPrivateKey;
+ RSAPrivateCrtKeySpec rsaPrivateCrtKeySpec = new RSAPrivateCrtKeySpec(
+ rsaPrivateCrtKey.getModulus(),
+ rsaPrivateCrtKey.getPublicExponent(),
+ rsaPrivateCrtKey.getPrivateExponent(),
+ rsaPrivateCrtKey.getPrimeP(),
+ rsaPrivateCrtKey.getPrimeQ(),
+ rsaPrivateCrtKey.getPrimeExponentP(),
+ rsaPrivateCrtKey.getPrimeExponentQ(),
+ rsaPrivateCrtKey.getCrtCoefficient()
+ );
+ RSAPrivateCrtKey rsaPrivateKey4 = (RSAPrivateCrtKey) factory.generatePrivate(
+ rsaPrivateCrtKeySpec);
+ if (!rsaPrivateKey.equals(rsaPrivateKey4)) {
+ throw new RuntimeException("rsaPrivateKey should equal to rsaPrivateKey4");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/rsa/SignatureTest.java Wed Sep 09 21:57:38 2015 +0000
@@ -0,0 +1,209 @@
+/*
+ * 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.Key;
+import java.security.KeyFactory;
+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 java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+import static javax.crypto.Cipher.PRIVATE_KEY;
+import static javax.crypto.Cipher.PUBLIC_KEY;
+import jdk.testlibrary.RandomFactory;
+
+/**
+ * @test
+ * @bug 8044199
+ * @summary Create a signature for RSA and get its signed data. re-initiate
+ * the signature with the public key. The signature can be verified
+ * by acquired signed data.
+ * @key randomness
+ * @library ../../../lib/testlibrary
+ * @run main SignatureTest MD2withRSA 512
+ * @run main SignatureTest MD5withRSA 512
+ * @run main SignatureTest SHA1withRSA 512
+ * @run main SignatureTest SHA256withRSA 512
+ * @run main SignatureTest MD2withRSA 768
+ * @run main SignatureTest MD5withRSA 768
+ * @run main SignatureTest SHA1withRSA 768
+ * @run main SignatureTest SHA256withRSA 768
+ * @run main SignatureTest MD2withRSA 1024
+ * @run main SignatureTest MD5withRSA 1024
+ * @run main SignatureTest SHA1withRSA 1024
+ * @run main SignatureTest SHA256withRSA 1024
+ * @run main SignatureTest MD2withRSA 2048
+ * @run main SignatureTest MD5withRSA 2048
+ * @run main SignatureTest SHA1withRSA 2048
+ * @run main SignatureTest SHA256withRSA 2048
+ * @run main/timeout=240 SignatureTest MD2withRSA 4096
+ * @run main/timeout=240 SignatureTest MD5withRSA 4096
+ * @run main/timeout=240 SignatureTest SHA1withRSA 4096
+ * @run main/timeout=240 SignatureTest SHA256withRSA 4096
+ * @run main/timeout=240 SignatureTest MD2withRSA 5120
+ * @run main/timeout=240 SignatureTest MD5withRSA 5120
+ * @run main/timeout=240 SignatureTest SHA1withRSA 5120
+ * @run main/timeout=240 SignatureTest SHA256withRSA 5120
+ * @run main/timeout=240 SignatureTest MD2withRSA 6144
+ * @run main/timeout=240 SignatureTest MD5withRSA 6144
+ * @run main/timeout=240 SignatureTest SHA1withRSA 6144
+ * @run main/timeout=240 SignatureTest SHA256withRSA 6144
+ */
+public class SignatureTest {
+ /**
+ * ALGORITHM name, fixed as RSA.
+ */
+ private static final String KEYALG = "RSA";
+
+ /**
+ * JDK default RSA Provider.
+ */
+ private static final String PROVIDER = "SunRsaSign";
+
+ /**
+ * How much times signature updated.
+ */
+ private static final int UPDATE_TIMES_FIFTY = 50;
+
+ /**
+ * How much times signature initial updated.
+ */
+ private static final int UPDATE_TIMES_HUNDRED = 100;
+
+ public static void main(String[] args) throws Exception {
+ String testAlg = args[0];
+ int testSize = Integer.parseInt(args[1]);
+
+ byte[] data = new byte[100];
+ RandomFactory.getRandom().nextBytes(data);
+
+ // create a key pair
+ KeyPair kpair = generateKeys(KEYALG, testSize);
+ Key[] privs = manipulateKey(PRIVATE_KEY, kpair.getPrivate());
+ Key[] pubs = manipulateKey(PUBLIC_KEY, kpair.getPublic());
+ // For signature algorithm, create and verify a signature
+
+ Arrays.stream(privs).forEach(priv
+ -> Arrays.stream(pubs).forEach(pub -> {
+ try {
+ checkSignature(data, (PublicKey) pub, (PrivateKey) priv,
+ testAlg);
+ } catch (NoSuchAlgorithmException | InvalidKeyException
+ | SignatureException | NoSuchProviderException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ ));
+
+ }
+
+ private static KeyPair generateKeys(String keyalg, int size)
+ throws NoSuchAlgorithmException {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyalg);
+ kpg.initialize(size);
+ return kpg.generateKeyPair();
+ }
+
+ private static Key[] manipulateKey(int type, Key key)
+ throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
+ KeyFactory kf = KeyFactory.getInstance(KEYALG, PROVIDER);
+
+ switch (type) {
+ case PUBLIC_KEY:
+ try {
+ kf.getKeySpec(key, RSAPrivateKeySpec.class);
+ throw new RuntimeException("Expected InvalidKeySpecException "
+ + "not thrown");
+ } catch (InvalidKeySpecException expected) {
+ }
+
+ return new Key[]{
+ kf.generatePublic(kf.getKeySpec(key, RSAPublicKeySpec.class)),
+ kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())),
+ kf.generatePublic(new RSAPublicKeySpec(
+ ((RSAPublicKey) key).getModulus(),
+ ((RSAPublicKey) key).getPublicExponent()))
+ };
+ case PRIVATE_KEY:
+ try {
+ kf.getKeySpec(key, RSAPublicKeySpec.class);
+ throw new RuntimeException("Expected InvalidKeySpecException"
+ + " not thrown");
+ } catch (InvalidKeySpecException expected) {
+ }
+ return new Key[]{
+ kf.generatePrivate(kf.getKeySpec(key,
+ RSAPrivateKeySpec.class)),
+ kf.generatePrivate(new PKCS8EncodedKeySpec(
+ key.getEncoded())),
+ kf.generatePrivate(new RSAPrivateKeySpec(((RSAPrivateKey) key).getModulus(),
+ ((RSAPrivateKey) key).getPrivateExponent()))
+ };
+ }
+ throw new RuntimeException("We shouldn't reach here");
+ }
+
+ private static void checkSignature(byte[] data, PublicKey pub,
+ PrivateKey priv, String sigalg) throws NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException, NoSuchProviderException {
+ Signature sig = Signature.getInstance(sigalg, PROVIDER);
+ sig.initSign(priv);
+ for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
+ sig.update(data);
+ }
+ byte[] signedData = sig.sign();
+
+ // Make sure signature verifies with original data
+ sig.initVerify(pub);
+ for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
+ sig.update(data);
+ }
+ if (!sig.verify(signedData)) {
+ throw new RuntimeException("Failed to verify " + sigalg
+ + " signature");
+ }
+
+ // Make sure signature does NOT verify when the original data
+ // has changed
+ sig.initVerify(pub);
+ for (int i = 0; i < UPDATE_TIMES_FIFTY; i++) {
+ sig.update(data);
+ }
+
+ if (sig.verify(signedData)) {
+ throw new RuntimeException("Failed to detect bad " + sigalg
+ + " signature");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/rsa/SpecTest.java Wed Sep 09 21:57:38 2015 +0000
@@ -0,0 +1,119 @@
+/*
+ * 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.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAKeyGenParameterSpec;
+
+/**
+ * @test
+ * @bug 8044199
+ * @summary Check same KeyPair's private key and public key have same modulus.
+ * also check public key's public exponent equals to given spec's public
+ * exponent.
+ * @run main SpecTest 512
+ * @run main SpecTest 768
+ * @run main SpecTest 1024
+ * @run main SpecTest 2048
+ * @run main/timeout=240 SpecTest 4096
+ * @run main/timeout=240 SpecTest 5120
+ */
+public class SpecTest {
+ /**
+ * ALGORITHM name, fixed as RSA.
+ */
+ private static final String KEYALG = "RSA";
+
+ /**
+ * JDK default RSA Provider.
+ */
+ private static final String PROVIDER = "SunRsaSign";
+
+ /**
+ *
+ * @param kpair test key pair
+ * @param pubExponent expected public exponent.
+ * @return true if test passed. false if test failed.
+ */
+ private static boolean specTest(KeyPair kpair, BigInteger pubExponent) {
+ boolean passed = true;
+ RSAPrivateKey priv = (RSAPrivateKey) kpair.getPrivate();
+ RSAPublicKey pub = (RSAPublicKey) kpair.getPublic();
+
+ // test the getModulus method
+ if ((priv instanceof RSAKey) && (pub instanceof RSAKey)) {
+ if (!priv.getModulus().equals(pub.getModulus())) {
+ System.err.println("priv.getModulus() = " + priv.getModulus());
+ System.err.println("pub.getModulus() = " + pub.getModulus());
+ passed = false;
+ }
+
+ if (!pubExponent.equals(pub.getPublicExponent())) {
+ System.err.println("pubExponent = " + pubExponent);
+ System.err.println("pub.getPublicExponent() = "
+ + pub.getPublicExponent());
+ passed = false;
+ }
+ }
+ return passed;
+ }
+
+ public static void main(String[] args) {
+ int failCount = 0;
+
+ // Test key size.
+ int size = Integer.parseInt(args[0]);
+
+ try {
+ KeyPairGenerator kpg1 = KeyPairGenerator.getInstance(KEYALG, PROVIDER);
+ kpg1.initialize(new RSAKeyGenParameterSpec(size,
+ RSAKeyGenParameterSpec.F4));
+ if (!specTest(kpg1.generateKeyPair(),
+ RSAKeyGenParameterSpec.F4)) {
+ failCount++;
+ }
+
+ KeyPairGenerator kpg2 = KeyPairGenerator.getInstance(KEYALG, PROVIDER);
+ kpg2.initialize(new RSAKeyGenParameterSpec(size,
+ RSAKeyGenParameterSpec.F0));
+ if (!specTest(kpg2.generateKeyPair(), RSAKeyGenParameterSpec.F0)) {
+ failCount++;
+ }
+ } catch (NoSuchAlgorithmException | NoSuchProviderException
+ | InvalidAlgorithmParameterException ex) {
+ ex.printStackTrace(System.err);
+ failCount++;
+ }
+
+ if (failCount != 0) {
+ throw new RuntimeException("There are " + failCount
+ + " tests failed.");
+ }
+ }
+}