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
30import java.io.*;
31import java.security.*;
32import java.security.spec.*;
33import java.util.*;
34import java.math.*;
35import javax.crypto.*;
36
37public 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}
439