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