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 }