1 /*
   2  * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug     7088989
  27  * @summary Ensure the RSA ciphers and signatures works correctly
  28  */
  29 
  30 import java.io.*;
  31 import java.security.*;
  32 import java.security.spec.*;
  33 import java.util.*;
  34 import java.math.*;
  35 import javax.crypto.*;
  36 
  37 public class TestRSA extends UcryptoTest {
  38 
  39     // KAT
  40     private static final byte PLAINTEXT[] = Arrays.copyOf
  41         (new String("Known plaintext message utilized" +
  42                     "for RSA Encryption &  Decryption" +
  43                     "block, SHA1, SHA256, SHA384  and" +
  44                     "SHA512 RSA Signature KAT tests.").getBytes(), 128);
  45 
  46     private static final byte MOD[] = {
  47         (byte)0xd5, (byte)0x84, (byte)0x95, (byte)0x07, (byte)0xf4, (byte)0xd0,
  48         (byte)0x1f, (byte)0x82, (byte)0xf3, (byte)0x79, (byte)0xf4, (byte)0x99,
  49         (byte)0x48, (byte)0x10, (byte)0xe1, (byte)0x71, (byte)0xa5, (byte)0x62,
  50         (byte)0x22, (byte)0xa3, (byte)0x4b, (byte)0x00, (byte)0xe3, (byte)0x5b,
  51         (byte)0x3a, (byte)0xcc, (byte)0x10, (byte)0x83, (byte)0xe0, (byte)0xaf,
  52         (byte)0x61, (byte)0x13, (byte)0x54, (byte)0x6a, (byte)0xa2, (byte)0x6a,
  53         (byte)0x2c, (byte)0x5e, (byte)0xb3, (byte)0xcc, (byte)0xa3, (byte)0x71,
  54         (byte)0x9a, (byte)0xb2, (byte)0x3e, (byte)0x78, (byte)0xec, (byte)0xb5,
  55         (byte)0x0e, (byte)0x6e, (byte)0x31, (byte)0x3b, (byte)0x77, (byte)0x1f,
  56         (byte)0x6e, (byte)0x94, (byte)0x41, (byte)0x60, (byte)0xd5, (byte)0x6e,
  57         (byte)0xd9, (byte)0xc6, (byte)0xf9, (byte)0x29, (byte)0xc3, (byte)0x40,
  58         (byte)0x36, (byte)0x25, (byte)0xdb, (byte)0xea, (byte)0x0b, (byte)0x07,
  59         (byte)0xae, (byte)0x76, (byte)0xfd, (byte)0x99, (byte)0x29, (byte)0xf4,
  60         (byte)0x22, (byte)0xc1, (byte)0x1a, (byte)0x8f, (byte)0x05, (byte)0xfe,
  61         (byte)0x98, (byte)0x09, (byte)0x07, (byte)0x05, (byte)0xc2, (byte)0x0f,
  62         (byte)0x0b, (byte)0x11, (byte)0x83, (byte)0x39, (byte)0xca, (byte)0xc7,
  63         (byte)0x43, (byte)0x63, (byte)0xff, (byte)0x33, (byte)0x80, (byte)0xe7,
  64         (byte)0xc3, (byte)0x78, (byte)0xae, (byte)0xf1, (byte)0x73, (byte)0x52,
  65         (byte)0x98, (byte)0x1d, (byte)0xde, (byte)0x5c, (byte)0x53, (byte)0x6e,
  66         (byte)0x01, (byte)0x73, (byte)0x0d, (byte)0x12, (byte)0x7e, (byte)0x77,
  67         (byte)0x03, (byte)0xf1, (byte)0xef, (byte)0x1b, (byte)0xc8, (byte)0xa8,
  68         (byte)0x0f, (byte)0x97
  69     };
  70 
  71     private static final byte PUB_EXP[] = {(byte)0x01, (byte)0x00, (byte)0x01};
  72 
  73     private static final byte PRIV_EXP[] = {
  74         (byte)0x85, (byte)0x27, (byte)0x47, (byte)0x61, (byte)0x4c, (byte)0xd4,
  75         (byte)0xb5, (byte)0xb2, (byte)0x0e, (byte)0x70, (byte)0x91, (byte)0x8f,
  76         (byte)0x3d, (byte)0x97, (byte)0xf9, (byte)0x5f, (byte)0xcc, (byte)0x09,
  77         (byte)0x65, (byte)0x1c, (byte)0x7c, (byte)0x5b, (byte)0xb3, (byte)0x6d,
  78         (byte)0x63, (byte)0x3f, (byte)0x7b, (byte)0x55, (byte)0x22, (byte)0xbb,
  79         (byte)0x7c, (byte)0x48, (byte)0x77, (byte)0xae, (byte)0x80, (byte)0x56,
  80         (byte)0xc2, (byte)0x10, (byte)0xd5, (byte)0x03, (byte)0xdb, (byte)0x31,
  81         (byte)0xaf, (byte)0x8d, (byte)0x54, (byte)0xd4, (byte)0x48, (byte)0x99,
  82         (byte)0xa8, (byte)0xc4, (byte)0x23, (byte)0x43, (byte)0xb8, (byte)0x48,
  83         (byte)0x0b, (byte)0xc7, (byte)0xbc, (byte)0xf5, (byte)0xcc, (byte)0x64,
  84         (byte)0x72, (byte)0xbf, (byte)0x59, (byte)0x06, (byte)0x04, (byte)0x1c,
  85         (byte)0x32, (byte)0xf5, (byte)0x14, (byte)0x2e, (byte)0x6e, (byte)0xe2,
  86         (byte)0x0f, (byte)0x5c, (byte)0xde, (byte)0x36, (byte)0x3c, (byte)0x6e,
  87         (byte)0x7c, (byte)0x4d, (byte)0xcc, (byte)0xd3, (byte)0x00, (byte)0x6e,
  88         (byte)0xe5, (byte)0x45, (byte)0x46, (byte)0xef, (byte)0x4d, (byte)0x25,
  89         (byte)0x46, (byte)0x6d, (byte)0x7f, (byte)0xed, (byte)0xbb, (byte)0x4f,
  90         (byte)0x4d, (byte)0x9f, (byte)0xda, (byte)0x87, (byte)0x47, (byte)0x8f,
  91         (byte)0x74, (byte)0x44, (byte)0xb7, (byte)0xbe, (byte)0x9d, (byte)0xf5,
  92         (byte)0xdd, (byte)0xd2, (byte)0x4c, (byte)0xa5, (byte)0xab, (byte)0x74,
  93         (byte)0xe5, (byte)0x29, (byte)0xa1, (byte)0xd2, (byte)0x45, (byte)0x3b,
  94         (byte)0x33, (byte)0xde, (byte)0xd5, (byte)0xae, (byte)0xf7, (byte)0x03,
  95         (byte)0x10, (byte)0x21
  96     };
  97 
  98     private static final byte PRIME_P[] = {
  99         (byte)0xf9, (byte)0x74, (byte)0x8f, (byte)0x16, (byte)0x02, (byte)0x6b,
 100         (byte)0xa0, (byte)0xee, (byte)0x7f, (byte)0x28, (byte)0x97, (byte)0x91,
 101         (byte)0xdc, (byte)0xec, (byte)0xc0, (byte)0x7c, (byte)0x49, (byte)0xc2,
 102         (byte)0x85, (byte)0x76, (byte)0xee, (byte)0x66, (byte)0x74, (byte)0x2d,
 103         (byte)0x1a, (byte)0xb8, (byte)0xf7, (byte)0x2f, (byte)0x11, (byte)0x5b,
 104         (byte)0x36, (byte)0xd8, (byte)0x46, (byte)0x33, (byte)0x3b, (byte)0xd8,
 105         (byte)0xf3, (byte)0x2d, (byte)0xa1, (byte)0x03, (byte)0x83, (byte)0x2b,
 106         (byte)0xec, (byte)0x35, (byte)0x43, (byte)0x32, (byte)0xff, (byte)0xdd,
 107         (byte)0x81, (byte)0x7c, (byte)0xfd, (byte)0x65, (byte)0x13, (byte)0x04,
 108         (byte)0x7c, (byte)0xfc, (byte)0x03, (byte)0x97, (byte)0xf0, (byte)0xd5,
 109         (byte)0x62, (byte)0xdc, (byte)0x0d, (byte)0xbf
 110     };
 111 
 112     private static final byte PRIME_Q[] = {
 113         (byte)0xdb, (byte)0x1e, (byte)0xa7, (byte)0x3d, (byte)0xe7, (byte)0xfa,
 114         (byte)0x8b, (byte)0x04, (byte)0x83, (byte)0x48, (byte)0xf3, (byte)0xa5,
 115         (byte)0x31, (byte)0x9d, (byte)0x35, (byte)0x5e, (byte)0x4d, (byte)0x54,
 116         (byte)0x77, (byte)0xcc, (byte)0x84, (byte)0x09, (byte)0xf3, (byte)0x11,
 117         (byte)0x0d, (byte)0x54, (byte)0xed, (byte)0x85, (byte)0x39, (byte)0xa9,
 118         (byte)0xca, (byte)0xa8, (byte)0xea, (byte)0xae, (byte)0x19, (byte)0x9c,
 119         (byte)0x75, (byte)0xdb, (byte)0x88, (byte)0xb8, (byte)0x04, (byte)0x8d,
 120         (byte)0x54, (byte)0xc6, (byte)0xa4, (byte)0x80, (byte)0xf8, (byte)0x93,
 121         (byte)0xf0, (byte)0xdb, (byte)0x19, (byte)0xef, (byte)0xd7, (byte)0x87,
 122         (byte)0x8a, (byte)0x8f, (byte)0x5a, (byte)0x09, (byte)0x2e, (byte)0x54,
 123         (byte)0xf3, (byte)0x45, (byte)0x24, (byte)0x29
 124     };
 125 
 126     private static final byte EXP_P[] = {
 127         (byte)0x6a, (byte)0xd1, (byte)0x25, (byte)0x80, (byte)0x18, (byte)0x33,
 128         (byte)0x3c, (byte)0x2b, (byte)0x44, (byte)0x19, (byte)0xfe, (byte)0xa5,
 129         (byte)0x40, (byte)0x03, (byte)0xc4, (byte)0xfc, (byte)0xb3, (byte)0x9c,
 130         (byte)0xef, (byte)0x07, (byte)0x99, (byte)0x58, (byte)0x17, (byte)0xc1,
 131         (byte)0x44, (byte)0xa3, (byte)0x15, (byte)0x7d, (byte)0x7b, (byte)0x22,
 132         (byte)0x22, (byte)0xdf, (byte)0x03, (byte)0x58, (byte)0x66, (byte)0xf5,
 133         (byte)0x24, (byte)0x54, (byte)0x52, (byte)0x91, (byte)0x2d, (byte)0x76,
 134         (byte)0xfe, (byte)0x63, (byte)0x64, (byte)0x4e, (byte)0x0f, (byte)0x50,
 135         (byte)0x2b, (byte)0x65, (byte)0x79, (byte)0x1f, (byte)0xf1, (byte)0xbf,
 136         (byte)0xc7, (byte)0x41, (byte)0x26, (byte)0xcc, (byte)0xc6, (byte)0x1c,
 137         (byte)0xa9, (byte)0x83, (byte)0x6f, (byte)0x03
 138     };
 139 
 140     private static final byte EXP_Q[] = {
 141         (byte)0x12, (byte)0x84, (byte)0x1a, (byte)0x99, (byte)0xce, (byte)0x9a,
 142         (byte)0x8b, (byte)0x58, (byte)0xcc, (byte)0x47, (byte)0x43, (byte)0xdf,
 143         (byte)0x77, (byte)0xbb, (byte)0xd3, (byte)0x20, (byte)0xae, (byte)0xe4,
 144         (byte)0x2e, (byte)0x63, (byte)0x67, (byte)0xdc, (byte)0xf7, (byte)0x5f,
 145         (byte)0x3f, (byte)0x83, (byte)0x27, (byte)0xb7, (byte)0x14, (byte)0x52,
 146         (byte)0x56, (byte)0xbf, (byte)0xc3, (byte)0x65, (byte)0x06, (byte)0xe1,
 147         (byte)0x03, (byte)0xcc, (byte)0x93, (byte)0x57, (byte)0x09, (byte)0x7b,
 148         (byte)0x6f, (byte)0xe8, (byte)0x81, (byte)0x4a, (byte)0x2c, (byte)0xb7,
 149         (byte)0x43, (byte)0xa9, (byte)0x20, (byte)0x1d, (byte)0xf6, (byte)0x56,
 150         (byte)0x8b, (byte)0xcc, (byte)0xe5, (byte)0x4c, (byte)0xd5, (byte)0x4f,
 151         (byte)0x74, (byte)0x67, (byte)0x29, (byte)0x51
 152     };
 153 
 154     private static final byte CRT_COEFF[] = {
 155         (byte)0x23, (byte)0xab, (byte)0xf4, (byte)0x03, (byte)0x2f, (byte)0x29,
 156         (byte)0x95, (byte)0x74, (byte)0xac, (byte)0x1a, (byte)0x33, (byte)0x96,
 157         (byte)0x62, (byte)0xed, (byte)0xf7, (byte)0xf6, (byte)0xae, (byte)0x07,
 158         (byte)0x2a, (byte)0x2e, (byte)0xe8, (byte)0xab, (byte)0xfb, (byte)0x1e,
 159         (byte)0xb9, (byte)0xb2, (byte)0x88, (byte)0x1e, (byte)0x85, (byte)0x05,
 160         (byte)0x42, (byte)0x64, (byte)0x03, (byte)0xb2, (byte)0x8b, (byte)0xc1,
 161         (byte)0x81, (byte)0x75, (byte)0xd7, (byte)0xba, (byte)0xaa, (byte)0xd4,
 162         (byte)0x31, (byte)0x3c, (byte)0x8a, (byte)0x96, (byte)0x23, (byte)0x9d,
 163         (byte)0x3f, (byte)0x06, (byte)0x3e, (byte)0x44, (byte)0xa9, (byte)0x62,
 164         (byte)0x2f, (byte)0x61, (byte)0x5a, (byte)0x51, (byte)0x82, (byte)0x2c,
 165         (byte)0x04, (byte)0x85, (byte)0x73, (byte)0xd1
 166     };
 167 
 168     private static KeyPair genRSAKey(int keyLength) throws Exception {
 169         KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
 170         kpg.initialize(keyLength);
 171         return kpg.generateKeyPair();
 172     }
 173 
 174     private static KeyPair genPredefinedRSAKeyPair(String prov) throws Exception {
 175         KeyFactory kf;
 176         if (prov == null) {
 177             kf = KeyFactory.getInstance("RSA");
 178             System.out.println("Using default KeyFactory:  "+kf.getProvider().getName());
 179         } else {
 180             kf = KeyFactory.getInstance("RSA", prov);
 181             System.out.println("Using specified KeyFactory:  "+kf.getProvider().getName());
 182         }
 183         BigInteger mod = new BigInteger(1, MOD);
 184         BigInteger pub = new BigInteger(1, PUB_EXP);
 185 
 186         PrivateKey privKey = kf.generatePrivate
 187             (new RSAPrivateCrtKeySpec
 188              (mod, pub, new BigInteger(1, PRIV_EXP),
 189               new BigInteger(1, PRIME_P), new BigInteger(1, PRIME_Q),
 190               new BigInteger(1, EXP_P), new BigInteger(1, EXP_Q),
 191               new BigInteger(1, CRT_COEFF)));
 192         PublicKey pubKey = kf.generatePublic(new RSAPublicKeySpec(mod, pub));
 193         return new KeyPair(pubKey, privKey);
 194     }
 195 
 196     private static final String CIP_ALGOS[] = {
 197         "RSA/ECB/NoPadding",
 198         "RSA/ECB/PKCS1Padding"
 199     };
 200     private static final int INPUT_SIZE_REDUCTION[] = {
 201         0,
 202         11,
 203     };
 204     private static final String SIG_ALGOS[] = {
 205         "MD5WithRSA",
 206         "SHA1WithRSA",
 207         "SHA256WithRSA",
 208         "SHA384WithRSA",
 209         "SHA512WithRSA"
 210     };
 211 
 212     private static KeyPair kp[] = null;
 213 
 214     public static void main(String argv[]) throws Exception {
 215         main(new TestRSA(), null);
 216     }
 217 
 218     public void doTest(Provider prov) throws Exception {
 219         // first test w/ predefine KeyPair
 220         System.out.println("Test against Predefined RSA Key Pair");
 221         KeyPair pkp = genPredefinedRSAKeyPair("SunPKCS11-Solaris");
 222         testCipher(pkp, 128, true, prov);
 223         testSignature(pkp, true, prov);
 224 
 225         pkp = genPredefinedRSAKeyPair("SunRsaSign");
 226         testCipher(pkp, 128, true, prov);
 227         testSignature(pkp, true, prov);
 228 
 229         pkp = genPredefinedRSAKeyPair(null);
 230         testCipher(pkp, 128, true, prov);
 231         testSignature(pkp, true, prov);
 232 
 233         System.out.println("Running key length test loop");
 234         for (int i = 0; i < 10; i++) {
 235             // then test w/ various key lengths
 236             int keyLens[] = { 1024, 2048 };
 237             kp = new KeyPair[keyLens.length];
 238 
 239             testCipher(keyLens, false, prov);
 240             testSignature(keyLens, false, prov);
 241         }
 242     }
 243 
 244 
 245     private static void testCipher(KeyPair kp, int inputSizeInBytes,
 246                                    boolean checkInterop, Provider prov)
 247         throws Exception {
 248         Cipher c1, c2;
 249         for (int i = 0; i < CIP_ALGOS.length; i++) {
 250             String algo = CIP_ALGOS[i];
 251             try {
 252                 c1 = Cipher.getInstance(algo, prov);
 253             } catch (NoSuchAlgorithmException nsae) {
 254                 System.out.println("Skip unsupported Cipher algo: " + algo);
 255                 continue;
 256             }
 257 
 258             if (checkInterop) {
 259                 c2 = Cipher.getInstance(algo, "SunJCE");
 260             } else {
 261                 c2 = Cipher.getInstance(algo, prov);
 262             }
 263             byte[] data = Arrays.copyOf
 264                  (PLAINTEXT, inputSizeInBytes - INPUT_SIZE_REDUCTION[i]);
 265 
 266             testEncryption(c1, c2, kp, data);
 267         }
 268     }
 269 
 270     private static void testCipher(int keyLens[], boolean checkInterop,
 271                                    Provider prov)
 272         throws Exception {
 273         // RSA CipherText will always differ due to the random nonce in padding
 274         // so we check whether both
 275         // 1) Java Encrypt/C Decrypt
 276         // 2) C Encrypt/Java Decrypt
 277         // works
 278         Cipher c1, c2;
 279         for (int i = 0; i < CIP_ALGOS.length; i++) {
 280             String algo = CIP_ALGOS[i];
 281             try {
 282                 c1 = Cipher.getInstance(algo, prov);
 283             } catch (NoSuchAlgorithmException nsae) {
 284                 System.out.println("Skip unsupported Cipher algo: " + algo);
 285                 continue;
 286             }
 287 
 288             if (checkInterop) {
 289                 c2 = Cipher.getInstance(algo, "SunJCE");
 290             } else {
 291                 c2 = Cipher.getInstance(algo, prov);
 292             }
 293 
 294             for (int h = 0; h < keyLens.length; h++) {
 295                 // Defer key pair generation until now when it'll soon be used.
 296                 if (kp[h] == null) {
 297                     kp[h] = genRSAKey(keyLens[h]);
 298                 }
 299                 System.out.println("\tTesting Cipher " + algo + " w/ KeySize " + keyLens[h]);
 300                 byte[] data = Arrays.copyOf
 301                     (PLAINTEXT, keyLens[h]/8 - INPUT_SIZE_REDUCTION[i]);
 302                 testEncryption(c1, c2, kp[h], data);
 303             }
 304         }
 305     }
 306 
 307     private static void testEncryption(Cipher c1, Cipher c2, KeyPair kp, byte[] data)
 308         throws Exception {
 309         // C1 Encrypt + C2 Decrypt
 310         byte[] out1 = null;
 311         byte[] recoveredText = null;
 312         try {
 313             c1.init(Cipher.ENCRYPT_MODE, kp.getPublic());
 314             out1 = c1.doFinal(data);
 315             c2.init(Cipher.DECRYPT_MODE, kp.getPrivate());
 316             recoveredText = c2.doFinal(out1);
 317         } catch (Exception ex) {
 318             System.out.println("\tDEC ERROR: unexpected exception");
 319             ex.printStackTrace();
 320             throw ex;
 321         }
 322         if(!Arrays.equals(recoveredText, data)) {
 323             throw new RuntimeException("\tDEC ERROR: different PT bytes!");
 324         }
 325         // C2 Encrypt + C1 Decrypt
 326         byte[] cipherText = null;
 327         try {
 328             c2.init(Cipher.ENCRYPT_MODE, kp.getPublic());
 329             cipherText = c2.doFinal(data);
 330             c1.init(Cipher.DECRYPT_MODE, kp.getPrivate());
 331             try {
 332                 out1 = c1.doFinal(cipherText);
 333             } catch (Exception ex) {
 334                 System.out.println("\tENC ERROR: invalid encrypted output");
 335                 ex.printStackTrace();
 336                 throw ex;
 337             }
 338         } catch (Exception ex) {
 339             System.out.println("\tENC ERROR: unexpected exception");
 340             ex.printStackTrace();
 341             throw ex;
 342         }
 343         if (!Arrays.equals(out1, data)) {
 344             throw new RuntimeException("\tENC ERROR: Decrypted result DIFF!");
 345         }
 346         System.out.println("\t=> PASS");
 347     }
 348 
 349     private static void testSignature(KeyPair kp, boolean checkInterop,
 350                                       Provider prov) throws Exception {
 351         byte[] data = PLAINTEXT;
 352         Signature sig1, sig2;
 353         for (int i = 0; i < SIG_ALGOS.length; i++) {
 354             String algo = SIG_ALGOS[i];
 355             try {
 356                 sig1 = Signature.getInstance(algo, prov);
 357             } catch (NoSuchAlgorithmException nsae) {
 358                 System.out.println("Skip unsupported Signature algo: " + algo);
 359                 continue;
 360             }
 361 
 362             if (checkInterop) {
 363                 sig2 = Signature.getInstance(algo, "SunRsaSign");
 364             } else {
 365                 sig2 = Signature.getInstance(algo, prov);
 366             }
 367             testSigning(sig1, sig2, kp, data);
 368         }
 369     }
 370 
 371     private static void testSignature(int keyLens[], boolean checkInterop,
 372                                       Provider prov) throws Exception {
 373         byte[] data = PLAINTEXT;
 374         Signature sig1, sig2;
 375         for (int i = 0; i < SIG_ALGOS.length; i++) {
 376             String algo = SIG_ALGOS[i];
 377             try {
 378                 sig1 = Signature.getInstance(algo, prov);
 379             } catch (NoSuchAlgorithmException nsae) {
 380                 System.out.println("Skip unsupported Signature algo: " + algo);
 381                 continue;
 382             }
 383 
 384             if (checkInterop) {
 385                 sig2 = Signature.getInstance(algo, "SunRsaSign");
 386             } else {
 387                 sig2 = Signature.getInstance(algo, prov);
 388             }
 389 
 390             for (int h = 0; h < keyLens.length; h++) {
 391                 // Defer key pair generation until now when it'll soon be used.
 392                 if (kp[h] == null) {
 393                     kp[h] = genRSAKey(keyLens[h]);
 394                 }
 395                 System.out.println("\tTesting Signature " + algo + " w/ KeySize " + keyLens[h]);
 396 
 397                 testSigning(sig1, sig2, kp[h], data);
 398             }
 399         }
 400     }
 401 
 402     private static void testSigning(Signature sig1, Signature sig2, KeyPair kp, byte[] data)
 403             throws Exception {
 404         boolean sameSig = false;
 405         byte[] out = null;
 406         try {
 407             sig1.initSign(kp.getPrivate());
 408             sig1.update(data);
 409             out = sig1.sign();
 410         } catch (Exception ex) {
 411             System.out.println("\tSIGN ERROR: unexpected exception!");
 412             ex.printStackTrace();
 413         }
 414 
 415         sig2.initSign(kp.getPrivate());
 416         sig2.update(data);
 417         byte[] out2 = sig2.sign();
 418         if (!Arrays.equals(out2, out)) {
 419             throw new RuntimeException("\tSIGN ERROR: Signature DIFF!");
 420         }
 421 
 422         boolean verify = false;
 423         try {
 424             System.out.println("\tVERIFY1 using native out");
 425             sig1.initVerify(kp.getPublic());
 426             sig1.update(data);
 427             verify = sig1.verify(out);
 428             if (!verify) {
 429                 throw new RuntimeException("VERIFY1 FAIL!");
 430             }
 431         } catch (Exception ex) {
 432             System.out.println("\tVERIFY1 ERROR: unexpected exception!");
 433             ex.printStackTrace();
 434             throw ex;
 435         }
 436         System.out.println("\t=> PASS");
 437     }
 438 }