1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18/**
19* @author Vladimir N. Molotkov
20* @version $Revision$
21*/
22
23package org.apache.harmony.crypto.tests.javax.crypto;
24
25import java.io.IOException;
26import java.security.AlgorithmParameters;
27import java.security.AlgorithmParametersSpi;
28import java.security.InvalidAlgorithmParameterException;
29import java.security.InvalidKeyException;
30import java.security.Key;
31import java.security.KeyPair;
32import java.security.KeyPairGenerator;
33import java.security.NoSuchAlgorithmException;
34import java.security.NoSuchProviderException;
35import java.security.Provider;
36import java.security.Security;
37import java.security.spec.InvalidKeySpecException;
38import java.security.spec.InvalidParameterSpecException;
39import java.security.spec.PKCS8EncodedKeySpec;
40import java.util.Arrays;
41
42import javax.crypto.BadPaddingException;
43import javax.crypto.Cipher;
44import javax.crypto.EncryptedPrivateKeyInfo;
45import javax.crypto.IllegalBlockSizeException;
46import javax.crypto.KeyGenerator;
47import javax.crypto.NoSuchPaddingException;
48import javax.crypto.SecretKeyFactory;
49import javax.crypto.spec.PBEKeySpec;
50import javax.crypto.spec.PBEParameterSpec;
51
52import org.apache.harmony.crypto.tests.support.EncryptedPrivateKeyInfoData;
53
54import junit.framework.TestCase;
55
56/**
57 * Test for EncryptedPrivateKeyInfo class.
58 *
59 * All binary data for this test were generated using BEA JRockit j2sdk1.4.2_04
60 * (http://www.bea.com) with security providers list extended by Bouncy Castle's
61 * one (http://www.bouncycastle.org)
62 */
63public class EncryptedPrivateKeyInfoTest extends TestCase {
64
65    private static final Provider[] provider = Security.getProviders();
66
67    /**
68     * Algorithm names/transformations used in roundtrip tests of
69     * getKeySpec(...) methods
70     */
71    private static final String[][] algName = {
72    // AES
73            { "AES", null},
74            //            {"AES", "AES/ECB/PKCS5Padding"},
75            //            {"AES", "AES/CBC/PKCS5Padding"},
76            //            {"AES", "AES/OFB/PKCS5Padding"},
77            //            {"AES", "AES/CFB/PKCS5Padding"},
78            //            {"2.16.840.1.101.3.4.1.1", null},
79            //            {"2.16.840.1.101.3.4.1.2", null},
80            //            {"2.16.840.1.101.3.4.1.3", null},
81            //            {"2.16.840.1.101.3.4.1.4", null},
82            //            {"2.16.840.1.101.3.4.1.5", null},
83            //            {"2.16.840.1.101.3.4.1.21", null},
84            //            {"2.16.840.1.101.3.4.1.22", null},
85            //            {"2.16.840.1.101.3.4.1.23", null},
86            //            {"2.16.840.1.101.3.4.1.24", null},
87            //            {"2.16.840.1.101.3.4.1.25", null},
88            //            {"2.16.840.1.101.3.4.1.41", null},
89            //            {"2.16.840.1.101.3.4.1.42", null},
90            //            {"2.16.840.1.101.3.4.1.43", null},
91            //            {"2.16.840.1.101.3.4.1.44", null},
92            //            {"2.16.840.1.101.3.4.1.45", null},
93
94            // Blowfish
95            // NO OIDs for Blowfish defined (?)
96            { "Blowfish", null },
97            //            {"Blowfish","Blowfish/CBC/PKCS5Padding"},
98            //            {"Blowfish","Blowfish/CFB/PKCS5Padding"},
99            //            {"Blowfish","Blowfish/OFB/PKCS5Padding"},
100            //            {"Blowfish","Blowfish/PCBC/PKCS5Padding"},
101
102            // DES: OIW OIDs only
103            // {iso(1) identified-organization(3) oiw(14) secsig(3)
104            // algorithms(2) desECB(6)}
105            // 1.3.14.3.2.6
106            // 1.3.14.3.2.7
107            // 1.3.14.3.2.8
108            // 1.3.14.3.2.9
109            { "DES", null },
110            //            {"DES", "DES/CBC/PKCS5Padding"},
111            //            {"DES","DES/CFB/PKCS5Padding"},
112            //            {"DES","DES/OFB/PKCS5Padding"},
113            //            {"DES","DES/PCBC/PKCS5Padding"},
114
115            // DESede (=TripleDes)
116            //{iso(1) identified-organization(3) oiw(14) secsig(3)
117            // algorithms(2) desEDE(17)}
118            // 1.3.14.3.2.17
119            //            {"DESede",null},
120            //            {"DESede","DESede/CBC/PKCS5Padding"},
121            //            {"DESede","DESede/CFB/PKCS5Padding"},
122            //            {"DESede","DESede/OFB/PKCS5Padding"},
123            //            {"DESede","DESede/PCBC/PKCS5Padding"},
124            { "TripleDES", null },
125            //            {"TripleDES","TripleDES/CBC/PKCS5Padding"},
126            //            {"TripleDES","TripleDES/CFB/PKCS5Padding"},
127            //            {"TripleDES","TripleDES/OFB/PKCS5Padding"},
128            //            {"TripleDES","TripleDES/PCBC/PKCS5Padding"},
129
130            // PBEWith<digest>And<encryption>
131            { "PBEWithMD5AndTripleDES", null },
132            // {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-5(5)
133            // pbeWithMD5AndDES-CBC(3)}
134            { "PBEWithMD5AndDES", "PBEWithMD5AndDES/CBC/PKCS5Padding", "PBEWithMD5AndDES"},
135            { "PBEWithMD5AndDES", null, "PBEWithMD5AndDES"}, { "PBEWithHmacSHA1AndDESede", null },
136            // more oids:
137            // {iso(1) member-body(2) us(840) nortelnetworks(113533) entrust(7)
138            // algorithms(66) pbeWithMD5AndCAST5-CBC(12)}
139            //
140            // also named pbeWithSHAAnd128BitRC4, pbeWithSHA1And128BitRC4:
141            // {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12)
142            // pkcs-12-PbeIds(1) pkcs-12-OfflineTransportMode(1)}
143            //
144            // {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-12(12)
145            // pkcs-12-PbeIds(1)} +
146            // pbeWithSHAAnd40BitRC4(2) pbeWithSHAAnd3-KeyTripleDES-CBC(3)
147            // pbeWithSHAAnd2-KeyTripleDES-CBC(4) pbeWithSHAAnd128BitRC2-CBC(5)
148            // pbeWithSHAAnd40BitRC2-CBC(6)
149
150            // DiffieHellman
151            { "DiffieHellman", null }, // 1.2.840.10046.2.1
152            //            {"DH",null}, // 1.2.840.10046.2.1
153            //            {"1.2.840.113549.1.3.1", null},
154
155            { "DSA", null }, // 1.2.840.10040.4.1
156
157            { "RC2", null },
158
159            { "RC4", null },
160
161            { "RC5", null },
162
163            //            {"1.2.840.113549.1.12.1.1",null},
164            //            {"1.2.840.113549.1.12.1.2",null},
165            //{ "1.2.840.113549.1.12.1.3", null, "PBEWithSHA1AndDESede"},
166            //{ "PBEWithSHA1AndDESede", null, "PBEWithSHA1AndDESede"},
167    //            {"1.2.840.113549.1.12.1.4",null},
168    //            {"1.2.840.113549.1.12.1.5",null},
169    //            {"1.2.840.113549.1.12.1.6",null},
170    //            {"ELGAMAL/PKCS1", "ELGAMAL/ECB/PKCS1PADDING"},
171    //            {"ELGAMAL/PKCS1","ELGAMAL/NONE/PKCS1PADDING"},
172    //            {"PBEWITHSHAAND3-KEYTRIPLEDES-CBC", null},
173    //            {"PBEWITHSHA1ANDDESEDE", null},
174    //            {"PBEWithSHAAnd3KeyTripleDES",null},
175    //            {"PBEWITHSHAAND3-KEYTRIPLEDES-CBC",null},
176    //
177    //            {"RC5-32",null},
178    //
179    //            {"RSA/1", "RSA/1/PKCS1PADDING"},
180    //            {"RSA/2", "RSA/2/PKCS1PADDING"},
181    //            {"RSA/ISO9796-1", "RSA/ECB/ISO9796-1PADDING"},
182    //            {"RSA", "RSA/ECB/NOPADDING"},
183    //            {"RSA/OAEP", "RSA/ECB/OAEPPADDING"},
184    //            {"RSA/PKCS1", "RSA/ECB/PKCS1PADDING"},
185    //            {"RSA/ISO9796-1", "RSA/NONE/ISO9796-1PADDING"},
186    //            {"RSA", "RSA/NONE/NOPADDING"},
187    //            {"RSA/OAEP", "RSA/NONE/OAEPPADDING"},
188    //            {"RSA/PKCS1", "RSA/NONE/PKCS1PADDING"},
189    //            {"RSA",null}, // 1.2.840.113549.1.1.1
190    //            {"1.2.840.113549.1.1.1", null},
191    };
192
193    @Override protected void setUp() throws Exception {
194        super.setUp();
195    }
196
197    public void test_getAlgName () {
198        boolean performed = false;
199        for (int i = 0; i < algName.length; i++) {
200            try {
201                // generate test data
202                TestDataGenerator g = new TestDataGenerator(algName[i][0],
203                        algName[i][1], privateKeyInfoDamaged, null);
204
205                // create test object
206                EncryptedPrivateKeyInfo epki;
207                if (g.ap() == null) {
208                    epki = new EncryptedPrivateKeyInfo(algName[i][0], g.ct());
209                } else {
210                    epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
211                }
212
213                // call methods under test
214                if (algName[i].length == 3) {
215                    assertEquals(algName[i][2], epki.getAlgName());
216                }
217
218                performed = true;
219            } catch (TestDataGenerator.AllowedFailure allowedFailure) {
220            } catch (NoSuchAlgorithmException allowedFailure) {
221            }
222        }
223        assertTrue("Test not performed", performed);
224    }
225
226    /**
227     * Test #1 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
228     * <br>
229     * Assertion: creates <code>EncryptedPrivateKeyInfo</code> instance <br>
230     * Test preconditions: valid parameters passed <br>
231     * Expected: must pass without any exceptions
232     *
233     * @throws IOException
234     * @throws NoSuchAlgorithmException
235     */
236    public final void testEncryptedPrivateKeyInfobyteArray1() throws Exception {
237        new EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfoData
238                .getValidEncryptedPrivateKeyInfoEncoding("DH"));
239    }
240
241    /**
242     * Test #2 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
243     * <br>
244     * Assertion: <code>NullPointerException</code> if encoding is
245     * <code>null</code><br>
246     * Test preconditions: <code>null</code> passed as a parameter <br>
247     * Expected: <code>NullPointerException</code>
248     *
249     * @throws IOException
250     */
251    public final void testEncryptedPrivateKeyInfobyteArray2()
252            throws IOException {
253        try {
254            new EncryptedPrivateKeyInfo(null);
255            fail(getName() + ": NullPointerException has not been thrown");
256        } catch (NullPointerException ok) {
257        }
258    }
259
260    /**
261     * Test #3 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
262     * <br>
263     * Assertion: <code>IOException</code> if encoding is wrong <br>
264     * Test preconditions: wrong encoding passed as a parameter <br>
265     * Expected: <code>IOException</code>
266     */
267    public final void testEncryptedPrivateKeyInfobyteArray3() {
268        try {
269            new EncryptedPrivateKeyInfo(new byte[0]);
270            fail(getName() + ": IOException has not been thrown");
271        } catch (IOException ok) {
272        }
273    }
274
275    /**
276     * Test #4 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
277     * <br>
278     * Assertion: <code>IOException</code> if encoding is wrong <br>
279     * Test preconditions: wrong encoding passed as a parameter <br>
280     * Expected: <code>IOException</code>
281     */
282    public final void testEncryptedPrivateKeyInfobyteArray4() {
283        try {
284            new EncryptedPrivateKeyInfo(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9,
285                    10 });
286            fail(getName() + ": IOException has not been thrown");
287        } catch (IOException ok) {
288        }
289    }
290
291    /**
292     * Test #5 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
293     * <br>
294     * Assertion: <code>IOException</code> if encoding is wrong <br>
295     * Test preconditions: wrong encoding passed as a parameter <br>
296     * Expected: <code>IOException</code>
297     */
298    public final void testEncryptedPrivateKeyInfobyteArray5() throws Exception {
299        byte[] enc = null;
300        try {
301            // 1: get valid encoding
302            enc = EncryptedPrivateKeyInfoData
303                    .getValidEncryptedPrivateKeyInfoEncoding("DSA");
304
305            // ... and corrupt it (set wrong alg OID length)
306            enc[9] = (byte) 6;
307
308            new EncryptedPrivateKeyInfo(enc);
309            fail(getName() + "(1): IOException has not been thrown");
310        } catch (IOException ok) {
311        }
312
313        try {
314            // 2: get valid encoding
315            enc = EncryptedPrivateKeyInfoData
316                    .getValidEncryptedPrivateKeyInfoEncoding("DSA");
317            // ... and corrupt it (set wrong encrypted data tag)
318            enc[307] = (byte) 6;
319            new EncryptedPrivateKeyInfo(enc);
320            fail(getName() + "(2): IOException has not been thrown");
321        } catch (IOException ok) {
322        }
323
324        try {
325            // 3: get valid encoding
326            enc = EncryptedPrivateKeyInfoData
327                    .getValidEncryptedPrivateKeyInfoEncoding("DSA");
328            // ... and corrupt it (set wrong encrypted data length)
329            enc[310] = (byte) 1;
330            new EncryptedPrivateKeyInfo(enc);
331            fail(getName() + "(3): IOException has not been thrown");
332        } catch (IOException ok) {
333        }
334
335        try {
336            // 4: get valid encoding
337            enc = EncryptedPrivateKeyInfoData
338                    .getValidEncryptedPrivateKeyInfoEncoding("DSA");
339            // ... and corrupt it (set wrong tag for alg params sequence)
340            enc[17] = (byte) 0x29;
341            EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(enc);
342
343            if (epki.getAlgParameters() == null) {
344                // This kind of encoding corruption can
345                // be only determined while AlgorithmParameters
346                // initialization BUT No AlgorithmParameters instance
347                // available for algName0[i][0].
348                // So just skip this sub test
349            } else {
350                fail(getName() + "(4): IOException has not been thrown");
351            }
352
353        } catch (IOException ok) {
354        }
355
356        try {
357            // 5: get valid encoding
358            enc = EncryptedPrivateKeyInfoData
359                    .getValidEncryptedPrivateKeyInfoEncoding("DSA");
360            // ... and corrupt it (set wrong length for alg params sequence)
361            enc[20] = (byte) 0x1d;
362            new EncryptedPrivateKeyInfo(enc);
363            fail(getName() + "(5): IOException has not been thrown");
364        } catch (IOException ok) {
365        }
366
367        try {
368            // 6: get valid encoding
369            enc = EncryptedPrivateKeyInfoData
370                    .getValidEncryptedPrivateKeyInfoEncoding("DSA");
371            // ... and corrupt it (set wrong length for alg params sequence)
372            enc[20] = (byte) 0x1f;
373            new EncryptedPrivateKeyInfo(enc);
374            fail(getName() + "(6): IOException has not been thrown");
375        } catch (IOException ok) {
376        }
377    }
378
379    /**
380     * Test #6 for <code>EncryptedPrivateKeyInfo(byte[])</code> constructor
381     * <br>
382     * Assertion: byte array is copied to prevent subsequent modification <br>
383     * Test preconditions: valid array passed then modified <br>
384     * Expected: getEncoded(), invoked after above modification, must return
385     * array as it was before the modification
386     *
387     * @throws IOException
388     */
389    public final void testEncryptedPrivateKeyInfobyteArray6() throws Exception {
390        byte[] encoded = EncryptedPrivateKeyInfoData
391                .getValidEncryptedPrivateKeyInfoEncoding("DSA");
392        byte[] encodedCopy = encoded.clone();
393        // pass valid array
394        EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(encodedCopy);
395        // modify array passed
396        encodedCopy[9] = (byte) 6;
397        // check that internal state has not been affected
398        assertTrue(Arrays.equals(encoded, epki.getEncoded()));
399    }
400
401    /**
402     * Test #1 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
403     * constructor <br>
404     * Assertion: creates <code>EncryptedPrivateKeyInfo</code> instance <br>
405     * Test preconditions: valid parameters passed <br>
406     * Expected: must pass without any exceptions
407     */
408    public final void testEncryptedPrivateKeyInfoStringbyteArray1() {
409        boolean performed = false;
410
411        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
412            try {
413                new EncryptedPrivateKeyInfo(
414                        EncryptedPrivateKeyInfoData.algName0[i][0],
415                        EncryptedPrivateKeyInfoData.encryptedData);
416                performed = true;
417            } catch (NoSuchAlgorithmException allowed) {
418            }
419        }
420
421        assertTrue("Test not performed", performed);
422    }
423
424    /**
425     * Test #2 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
426     * constructor <br>
427     * Assertion: <code>NoSuchAlgorithmException</code>- if the specified
428     * algorithm is not supported <br>
429     * Test preconditions: pass nonexistent algorithm name <br>
430     * Expected: <code>NoSuchAlgorithmException</code>
431     */
432    public final void testEncryptedPrivateKeyInfoStringbyteArray2() {
433        try {
434            new EncryptedPrivateKeyInfo("bla-bla",
435                    EncryptedPrivateKeyInfoData.encryptedData);
436            fail(getName() + ": NoSuchAlgorithmException has not been thrown");
437        } catch (NoSuchAlgorithmException ok) {
438        }
439
440        try {
441            new EncryptedPrivateKeyInfo("",
442                    EncryptedPrivateKeyInfoData.encryptedData);
443            fail(getName() + ": NoSuchAlgorithmException has not been thrown");
444        } catch (NoSuchAlgorithmException ok) {
445        }
446    }
447
448    /**
449     * Test #3 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
450     * constructor <br>
451     * Assertion: <code>NullPointerException</code>- if the specified
452     * algorithm or encrypted data is <code>null</code><br>
453     * Test preconditions: pass <code>null</code> as algorithm name then as
454     * encrypted data <br>
455     * Expected: <code>NullPointerException</code> in both cases
456     *
457     * @throws NoSuchAlgorithmException
458     */
459    public final void testEncryptedPrivateKeyInfoStringbyteArray3()
460            throws NoSuchAlgorithmException {
461        // pass null as name
462        try {
463            new EncryptedPrivateKeyInfo((String) null,
464                    EncryptedPrivateKeyInfoData.encryptedData);
465            fail(getName() + ": NullPointerException has not been thrown");
466        } catch (NullPointerException ok) {
467        }
468
469        // pass null as encrypted data
470        try {
471            new EncryptedPrivateKeyInfo("DSA", null);
472            fail(getName() + ": NullPointerException has not been thrown");
473        } catch (NullPointerException ok) {
474        }
475    }
476
477    /**
478     * Test #4 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
479     * constructor <br>
480     * Assertion: <code>IllegalArgumentException</code>- if encrypted data is
481     * empty, i.e. 0-length <br>
482     * Test preconditions: pass empty encrypted data <br>
483     * Expected: <code>IllegalArgumentException</code>
484     */
485    public final void testEncryptedPrivateKeyInfoStringbyteArray4()
486            throws Exception {
487        try {
488            new EncryptedPrivateKeyInfo("DSA", new byte[] {});
489            fail(getName() + ": IllegalArgumentException has not been thrown");
490        } catch (IllegalArgumentException ok) {
491        }
492    }
493
494    /**
495     * Test #5 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
496     * constructor <br>
497     * Assertion: byte array is copied to prevent subsequent modification <br>
498     * Test preconditions: valid array passed then modified <br>
499     * Expected: getEncryptedData(), invoked after above modification, must
500     * return array as it was before the modification
501     *
502     * @throws IOException
503     */
504    public final void testEncryptedPrivateKeyInfoStringbyteArray5()
505            throws Exception {
506        byte[] encryptedDataCopy = EncryptedPrivateKeyInfoData.encryptedData
507                .clone();
508        // pass valid array
509        EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo("DSA",
510                encryptedDataCopy);
511        // modify array passed
512        encryptedDataCopy[0] = (byte) 6;
513        // check that internal state has not been affected
514        assertTrue(Arrays.equals(EncryptedPrivateKeyInfoData.encryptedData,
515                epki.getEncryptedData()));
516    }
517
518    /**
519     * javax/crypto/EncryptedPrivateKeyInfo(String, byte[])
520     * Checks exception order
521     */
522    public final void testEncryptedPrivateKeyInfoStringbyteArray6() {
523        //Regression for HARMONY-768
524        try {
525            new EncryptedPrivateKeyInfo("0", new byte[] {});
526            fail("NoSuchAlgorithmException expected");
527        } catch (NoSuchAlgorithmException e) {
528            //expected
529        }
530    }
531
532    class Mock_AlgorithmParameters extends AlgorithmParameters {
533        protected Mock_AlgorithmParameters(AlgorithmParametersSpi paramSpi, Provider provider, String algorithm) {
534            super(paramSpi, provider, algorithm);
535        }
536    }
537
538/**
539     * Test #1 for
540     * <code>EncryptedPrivateKeyInfo(java.security.AlgorithmParameters, byte[])
541     * </code>
542     * constructor <br>
543     * Assertion: creates <code>EncryptedPrivateKeyInfo</code> instance <br>
544     * Test preconditions: valid parameters passed <br>
545     * Expected: must pass without any exceptions
546     *
547     * @throws IOException
548     * @throws NoSuchAlgorithmException
549     */
550    public final void testEncryptedPrivateKeyInfoAlgorithmParametersbyteArray1()
551            throws IOException, NoSuchAlgorithmException {
552        AlgorithmParameters ap = null;
553
554        boolean performed = false;
555        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
556            try {
557                ap = AlgorithmParameters
558                        .getInstance(EncryptedPrivateKeyInfoData.algName0[i][0]);
559                // use pregenerated AlgorithmParameters encodings
560                ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding(
561                        EncryptedPrivateKeyInfoData.algName0[i][0]));
562
563                new EncryptedPrivateKeyInfo(ap,
564                        EncryptedPrivateKeyInfoData.encryptedData);
565
566                performed = true;
567            } catch (NoSuchAlgorithmException allowedFailure) {
568            }
569        }
570        assertTrue("Test not performed", performed);
571
572        ap = new Mock_AlgorithmParameters(null, null, "Wrong alg name");
573
574        try {
575            new EncryptedPrivateKeyInfo(ap,
576                EncryptedPrivateKeyInfoData.encryptedData);
577            fail("NoSuchAlgorithmException expected");
578        } catch (NoSuchAlgorithmException e) {
579            //expected
580        }
581    }
582
583    /**
584     * Test #2 for
585     * <code>EncryptedPrivateKeyInfo(java.security.AlgorithmParameters, byte[])
586     * </code>
587     * constructor <br>
588     * Assertion: <code>NullPointerException</code>- if the specified
589     * algorithm parameters or encrypted data is <code>null</code><br>
590     * Test preconditions: pass <code>null</code> as algorithm parameters then
591     * as encrypted data <br>
592     * Expected: <code>NullPointerException</code> in both cases
593     *
594     * @throws NoSuchAlgorithmException
595     * @throws IOException
596     */
597    public final void testEncryptedPrivateKeyInfoAlgorithmParametersbyteArray2()
598            throws NoSuchAlgorithmException, IOException {
599        // 1: pass null as AlgorithmParameters
600        try {
601            new EncryptedPrivateKeyInfo((AlgorithmParameters) null,
602                    EncryptedPrivateKeyInfoData.encryptedData);
603            fail(getName() + ": NullPointerException has not been thrown");
604        } catch (NullPointerException ok) {
605        }
606
607        // 2: pass null as encrypted data
608        try {
609            AlgorithmParameters ap = AlgorithmParameters.getInstance("DSA");
610            // use pregenerated AlgorithmParameters encodings
611            ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding("DSA"));
612            new EncryptedPrivateKeyInfo(ap, null);
613            fail(getName() + ": NullPointerException has not been thrown");
614        } catch (NullPointerException ok) {
615        }
616    }
617
618    /**
619     * Test #3 for
620     * <code>EncryptedPrivateKeyInfo(java.security.AlgorithmParameters, byte[])
621     * </code>
622     * constructor <br>
623     * Assertion: <code>IllegalArgumentException</code>- if encrypted data is
624     * empty, i.e. 0-length <br>
625     * Test preconditions: pass empty encrypted data <br>
626     * Expected: <code>IllegalArgumentException</code>
627     *
628     * @throws NoSuchAlgorithmException
629     * @throws IOException
630     */
631    public final void testEncryptedPrivateKeyInfoAlgorithmParametersbyteArray3()
632            throws Exception {
633        try {
634            AlgorithmParameters ap = AlgorithmParameters.getInstance("DSA");
635            // use pregenerated AlgorithmParameters encodings
636            ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding("DSA"));
637
638            new EncryptedPrivateKeyInfo(ap, new byte[] {});
639            fail(getName() + ": IllegalArgumentException has not been thrown");
640
641        } catch (IllegalArgumentException ok) {
642        }
643    }
644
645    /**
646     * Test #4 for
647     * <code>EncryptedPrivateKeyInfo(java.security.AlgorithmParameters, byte[])
648     * </code>
649     * constructor <br>
650     * Assertion: byte array is copied to prevent subsequent modification <br>
651     * Test preconditions: valid array passed then modified <br>
652     * Expected: getEncryptedData(), invoked after above modification, must
653     * return array as it was before the modification
654     *
655     * @throws IOException
656     */
657    public final void testEncryptedPrivateKeyInfoAlgorithmParametersbyteArray4()
658            throws Exception {
659        AlgorithmParameters ap = AlgorithmParameters.getInstance("DSA");
660        // use pregenerated AlgorithmParameters encodings
661        ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding("DSA"));
662
663        byte[] encryptedDataCopy = EncryptedPrivateKeyInfoData.encryptedData.clone();
664        // pass valid array
665        EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(ap,
666                encryptedDataCopy);
667
668        // modify array passed
669        encryptedDataCopy[0] = (byte) 6;
670
671        // check that internal state has not been affected
672        assertTrue(Arrays.equals(EncryptedPrivateKeyInfoData.encryptedData,
673                epki.getEncryptedData()));
674    }
675
676    /**
677     * Test #1 for <code>getAlgParameters()</code> method <br>
678     * Assertion: returns the algorithm parameters <br>
679     * Test preconditions: test object created using ctor which takes encoded
680     * form as the only parameter; encoded form passed contains algorithm
681     * parameters encoding <br>
682     * Expected: corresponding algorithm parameters must be returned
683     *
684     * @throws IOException
685     */
686    public final void testGetAlgParameters01() throws IOException {
687        boolean performed = false;
688        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
689            try {
690                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
691                        EncryptedPrivateKeyInfoData
692                                .getValidEncryptedPrivateKeyInfoEncoding(
693                                        EncryptedPrivateKeyInfoData.algName0[i][0]));
694
695                AlgorithmParameters apar = epki.getAlgParameters();
696                if (apar == null) {
697                    continue;
698                }
699
700                // check that method under test returns
701                // parameters with the same encoded form
702                assertTrue(Arrays
703                        .equals(
704                                EncryptedPrivateKeyInfoData
705                                        .getParametersEncoding(EncryptedPrivateKeyInfoData.algName0[i][0]),
706                                apar.getEncoded()));
707                performed = true;
708            } catch (NoSuchAlgorithmException allowedFailure) {
709            }
710        }
711        assertTrue("Test not performed", performed);
712    }
713
714    public final void testGetAlgParameters01_01() throws Exception {
715        byte[] validEncodingWithUnknownAlgOID = EncryptedPrivateKeyInfoData
716                .getValidEncryptedPrivateKeyInfoEncoding("DH");
717        // correct oid value
718        validEncodingWithUnknownAlgOID[18] = 0;
719        EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
720                validEncodingWithUnknownAlgOID);
721
722        assertNull(epki.getAlgParameters());
723    }
724
725    /**
726     * Test #2 for <code>getAlgParameters()</code> method <br>
727     * Assertion: returns the algorithm parameters <br>
728     * Test preconditions: test object created using ctor which takes encoded
729     * form as the only parameter; encoded form passed does not contain
730     * algorithm parameters encoding <br>
731     * Expected: <code>null</code> must be returned
732     *
733     * @throws IOException
734     */
735    public final void testGetAlgParameters02() throws IOException {
736        boolean performed = false;
737        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
738            try {
739                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
740                        EncryptedPrivateKeyInfoData
741                                .getValidEncryptedPrivateKeyInfoEncoding(
742                                        EncryptedPrivateKeyInfoData.algName0[i][0],
743                                        false));
744
745                // check that method under test returns null
746                assertNull(epki.getAlgParameters());
747
748                performed = true;
749            } catch (NoSuchAlgorithmException allowedFailure) {
750            }
751        }
752        assertTrue("Test not performed", performed);
753    }
754
755    /**
756     * Test #3 for <code>getAlgParameters()</code> method <br>
757     * Assertion: returns the algorithm parameters <br>
758     * Test #6 for <code>EncryptedPrivateKeyInfo(String, byte[])</code>
759     * constructor <br>
760     * Assertion: ...This constructor will use null as the value of the
761     * algorithm parameters. <br>
762     * Test preconditions: test object created using ctor which takes algorithm
763     * name and encrypted data as a parameters <br>
764     * Expected: <code>null</code> must be returned
765     *
766     * @throws IOException
767     */
768    public final void testGetAlgParameters03() throws IOException {
769        boolean performed = false;
770        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
771            try {
772                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
773                        EncryptedPrivateKeyInfoData.algName0[i][0],
774                        EncryptedPrivateKeyInfoData.encryptedData);
775
776                // check that method under test returns null
777                // for object constructed in such a way
778                assertNull(epki.getAlgParameters());
779
780                performed = true;
781            } catch (NoSuchAlgorithmException allowedFailure) {
782            }
783        }
784        assertTrue("Test not performed", performed);
785    }
786
787    /**
788     * Test #4 for <code>getAlgParameters()</code> method <br>
789     * Assertion: returns the algorithm parameters <br>
790     * Test preconditions: test object created using ctor which takes
791     * AlgorithmParameters and encrypted data as a parameters; <br>
792     * Expected: the same algorithm parameters as ones passed to the ctor must be
793     * returned
794     *
795     * @throws IOException
796     */
797    public final void testGetAlgParameters04() throws IOException {
798        boolean performed = false;
799        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
800            try {
801                AlgorithmParameters ap = AlgorithmParameters
802                        .getInstance(EncryptedPrivateKeyInfoData.algName0[i][0]);
803                // use pregenerated AlgorithmParameters encodings
804                ap
805                        .init(EncryptedPrivateKeyInfoData
806                                .getParametersEncoding(
807                                        EncryptedPrivateKeyInfoData.algName0[i][0]));
808
809                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(ap,
810                        EncryptedPrivateKeyInfoData.encryptedData);
811
812                // check that method under test returns
813                // the same parameters instance
814                assertSame(ap, epki.getAlgParameters());
815
816                performed = true;
817            } catch (NoSuchAlgorithmException allowedFailure) {
818            }
819        }
820        assertTrue("Test not performed", performed);
821    }
822
823    /**
824     * Test #1 for <code>getEncryptedData()</code> method <br>
825     * Assertion: returns the encrypted data <br>
826     * Test preconditions: test object created using ctor which takes encoded
827     * form as the only parameter; encoded form passed contains encrypted data
828     * <br>
829     * Expected: the equivalent encrypted data must be returned
830     *
831     * @throws IOException
832     */
833    public final void testGetEncryptedData01() throws IOException {
834        boolean performed = false;
835        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
836            try {
837                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
838                        EncryptedPrivateKeyInfoData
839                                .getValidEncryptedPrivateKeyInfoEncoding(
840                                        EncryptedPrivateKeyInfoData.algName0[i][0]));
841
842                // check that method under test returns
843                // valid encrypted data
844                assertTrue(Arrays.equals(
845                        EncryptedPrivateKeyInfoData.encryptedData, epki
846                                .getEncryptedData()));
847
848                performed = true;
849            } catch (NoSuchAlgorithmException allowedFailure) {
850            }
851        }
852        assertTrue("Test not performed", performed);
853    }
854
855    /**
856     * Test #2 for <code>getEncryptedData()</code> method <br>
857     * Assertion: returns the encrypted data <br>
858     * Test preconditions: test object created using ctor which takes algorithm
859     * name and encrypted data as a parameters <br>
860     * Expected: the equivalent encrypted data must be returned
861     */
862    public final void testGetEncryptedData02() {
863        boolean performed = false;
864        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
865            try {
866                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
867                        EncryptedPrivateKeyInfoData.algName0[i][0],
868                        EncryptedPrivateKeyInfoData.encryptedData);
869
870                // check that method under test returns
871                // valid encrypted data
872                assertTrue(Arrays.equals(
873                        EncryptedPrivateKeyInfoData.encryptedData, epki
874                                .getEncryptedData()));
875
876                performed = true;
877            } catch (NoSuchAlgorithmException allowedFailure) {
878            }
879        }
880        assertTrue("Test not performed", performed);
881    }
882
883    /**
884     * Test #3 for <code>getEncryptedData()</code> method <br>
885     * Assertion: returns the encrypted data <br>
886     * Test preconditions: test object created using ctor which takes algorithm
887     * parameters and encrypted data as a parameters <br>
888     * Expected: the equivalent encrypted data must be returned
889     *
890     * @throws IOException
891     */
892    public final void testGetEncryptedData03() throws IOException {
893        boolean performed = false;
894        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
895            try {
896                AlgorithmParameters ap = AlgorithmParameters
897                        .getInstance(EncryptedPrivateKeyInfoData.algName0[i][0]);
898                // use pregenerated AlgorithmParameters encodings
899                ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding(
900                        EncryptedPrivateKeyInfoData.algName0[i][0]));
901
902                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(ap,
903                        EncryptedPrivateKeyInfoData.encryptedData);
904
905                // check that method under test returns
906                // valid encrypted data
907                assertTrue(Arrays.equals(
908                        EncryptedPrivateKeyInfoData.encryptedData, epki
909                                .getEncryptedData()));
910
911                performed = true;
912            } catch (NoSuchAlgorithmException allowedFailure) {
913            }
914        }
915        assertTrue("Test not performed", performed);
916    }
917
918    /**
919     * Test #4 for <code>getEncryptedData()</code> method <br>
920     * Assertion: returns a new array each time this method is called <br>
921     * Test preconditions: test object created using ctor which takes algorithm
922     * name and encrypted data as a parameters <br>
923     * Expected: refs to encrypted data byte array passed to the ctor and
924     * returned by the method under test must be different
925     */
926    public final void testGetEncryptedData04() {
927        boolean performed = false;
928        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
929            try {
930                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
931                        EncryptedPrivateKeyInfoData.algName0[i][0],
932                        EncryptedPrivateKeyInfoData.encryptedData);
933
934                // check that method under test returns
935                // new array each time
936                byte[] ecd1 = epki.getEncryptedData();
937                byte[] ecd2 = epki.getEncryptedData();
938                assertNotSame(EncryptedPrivateKeyInfoData.encryptedData, ecd1);
939                assertNotSame(EncryptedPrivateKeyInfoData.encryptedData, ecd2);
940                assertNotSame(ecd1, ecd2);
941
942                performed = true;
943            } catch (NoSuchAlgorithmException allowedFailure) {
944            }
945        }
946        assertTrue("Test not performed", performed);
947    }
948
949    /**
950     * Test #1 for <code>getEncoded()</code> method <br>
951     * Assertion: returns the ASN.1 encoding of this object <br>
952     * Test preconditions: test object created using ctor which takes encoded
953     * form as the only parameter <br>
954     * Expected: equivalent encoded form must be returned
955     *
956     * @throws IOException
957     */
958    public final void testGetEncoded01() throws IOException {
959        boolean performed = false;
960        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
961            try {
962                byte[] enc = EncryptedPrivateKeyInfoData
963                        .getValidEncryptedPrivateKeyInfoEncoding(
964                                EncryptedPrivateKeyInfoData.algName0[i][0]);
965                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(enc);
966
967                // check that method under test returns
968                // valid encoded form
969                assertTrue(Arrays.equals(enc, epki.getEncoded()));
970
971                performed = true;
972            } catch (NoSuchAlgorithmException allowedFailure) {
973            }
974        }
975        assertTrue("Test not performed", performed);
976    }
977
978    /**
979     * Test #2 for <code>getEncoded()</code> method <br>
980     * Assertion: returns the ASN.1 encoding of this object <br>
981     * Test preconditions: test object created using ctor which takes algorithm
982     * name and encrypted data as a parameters <br>
983     * Expected: equivalent encoded form (without alg params) must be returned
984     *
985     * @throws IOException
986     */
987    public final void testGetEncoded02() throws IOException {
988        boolean performed = false;
989        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
990            try {
991                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
992                        EncryptedPrivateKeyInfoData.algName0[i][0],
993                        EncryptedPrivateKeyInfoData.encryptedData);
994
995                // check that method under test returns
996                // valid encoded form
997                byte[] refEnc = EncryptedPrivateKeyInfoData
998                        .getValidEncryptedPrivateKeyInfoEncoding(
999                                EncryptedPrivateKeyInfoData.algName0[i][0],
1000                                false);
1001                //                System.out.println(Array.toString(refEnc, " "));
1002                byte[] actEnc = epki.getEncoded();
1003                //                System.out.println(Array.toString(actEnc, " "));
1004                assertTrue(Arrays.equals(refEnc, actEnc));
1005
1006                performed = true;
1007            } catch (NoSuchAlgorithmException allowedFailure) {
1008            }
1009        }
1010        assertTrue("Test not performed", performed);
1011    }
1012
1013    /**
1014     * Test #3 for <code>getEncoded()</code> method <br>
1015     * Assertion: returns the ASN.1 encoding of this object <br>
1016     * Test preconditions: test object created using ctor which takes algorithm
1017     * name and encrypted data as a parameters <br>
1018     * Expected: equivalent encoded form (without alg params) must be returned
1019     *
1020     * @throws IOException
1021     */
1022    public final void testGetEncoded03() throws IOException {
1023        boolean performed = false;
1024        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
1025            try {
1026                AlgorithmParameters ap = AlgorithmParameters
1027                        .getInstance(EncryptedPrivateKeyInfoData.algName0[i][0]);
1028                // use pregenerated AlgorithmParameters encodings
1029                ap.init(EncryptedPrivateKeyInfoData.getParametersEncoding(
1030                        EncryptedPrivateKeyInfoData.algName0[i][0]));
1031
1032                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(ap,
1033                        EncryptedPrivateKeyInfoData.encryptedData);
1034
1035                // check that method under test returns
1036                // valid encoded form
1037                assertTrue(Arrays.equals(
1038                        EncryptedPrivateKeyInfoData
1039                            .getValidEncryptedPrivateKeyInfoEncoding(
1040                                EncryptedPrivateKeyInfoData.algName0[i][0]),
1041                                epki.getEncoded()));
1042
1043                performed = true;
1044            } catch (NoSuchAlgorithmException allowedFailure) {
1045            }
1046        }
1047        assertTrue("Test not performed", performed);
1048    }
1049
1050    /**
1051     * Test #4 for <code>getEncoded()</code> method <br>
1052     * Assertion: returns a new array each time this method is called <br>
1053     * Test preconditions: test object created using ctor which takes algorithm
1054     * name and encrypted data as a parameters <br>
1055     * Expected: several refs to byte array returned by the method under test
1056     * must be different
1057     *
1058     * @throws IOException
1059     */
1060    public final void testGetEncoded04() throws IOException {
1061        boolean performed = false;
1062        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
1063            try {
1064                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
1065                        EncryptedPrivateKeyInfoData.algName0[i][0],
1066                        EncryptedPrivateKeyInfoData.encryptedData);
1067
1068                // check that method under test returns
1069                // new array each time
1070                byte[] ec1 = epki.getEncoded();
1071                byte[] ec2 = epki.getEncoded();
1072                byte[] ec3 = epki.getEncoded();
1073                assertNotSame(ec1, ec2);
1074                assertNotSame(ec2, ec3);
1075                assertNotSame(ec1, ec3);
1076
1077                performed = true;
1078            } catch (NoSuchAlgorithmException allowedFailure) {
1079            }
1080        }
1081        assertTrue("Test not performed", performed);
1082    }
1083
1084    public final void testGetKeySpecCipher01() {
1085        boolean performed = false;
1086        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
1087            try {
1088                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
1089                        EncryptedPrivateKeyInfoData.algName0[i][0],
1090                        EncryptedPrivateKeyInfoData.encryptedData);
1091
1092                try {
1093
1094                    // check that method under test throws NPE
1095                    epki.getKeySpec((Cipher) null);
1096                    fail(getName() + "NullPointerException has not been thrown");
1097
1098                } catch (NullPointerException ok) {
1099                } catch (InvalidKeySpecException e) {
1100                    fail(getName() + "Unexpected exception: " + e);
1101                }
1102
1103                performed = true;
1104            } catch (NoSuchAlgorithmException allowedFailure) {
1105            }
1106        }
1107        assertTrue("Test not performed", performed);
1108    }
1109
1110    /**
1111     * Encrypted data contains valid PKCS8 key info encoding
1112     */
1113    public final void test_ROUNDTRIP_GetKeySpecCipher01() {
1114        boolean performed = false;
1115
1116        for (int i = 0; i < algName.length; i++) {
1117            try {
1118                // generate test data
1119                TestDataGenerator g = new TestDataGenerator(algName[i][0],
1120                        algName[i][1], privateKeyInfo, null);
1121
1122                // create test object
1123                EncryptedPrivateKeyInfo epki;
1124                if (g.ap() == null) {
1125                    epki = new EncryptedPrivateKeyInfo(algName[i][0], g.ct());
1126                } else {
1127                    epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
1128                }
1129
1130                // call methods under test
1131                try {
1132
1133                    PKCS8EncodedKeySpec eks = epki.getKeySpec(g.c());
1134
1135                    if (!Arrays.equals(privateKeyInfo, eks.getEncoded())) {
1136                        fail(algName[i][0] + " != " + algName[i][1]);
1137                    }
1138                } catch (InvalidKeySpecException e) {
1139                    fail(algName[i][0] + ", " + algName[i][1] + e + "\n");
1140                }
1141                performed = true;
1142
1143            } catch (TestDataGenerator.AllowedFailure allowedFailure) {
1144            } catch (NoSuchAlgorithmException allowed) {
1145            }
1146        }
1147        assertTrue("Test not performed", performed);
1148    }
1149
1150    /**
1151     * Encrypted data contains invalid PKCS8 key info encoding
1152     */
1153    public final void test_ROUNDTRIP_GetKeySpecCipher02() {
1154        boolean performed = false;
1155        for (int i = 0; i < algName.length; i++) {
1156            try {
1157                // generate test data
1158                TestDataGenerator g = new TestDataGenerator(algName[i][0],
1159                        algName[i][1], privateKeyInfoDamaged, null);
1160
1161                // create test object
1162                EncryptedPrivateKeyInfo epki;
1163                if (g.ap() == null) {
1164                    epki = new EncryptedPrivateKeyInfo(algName[i][0], g.ct());
1165                } else {
1166                    epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
1167                }
1168
1169                // call methods under test
1170                try {
1171                    epki.getKeySpec(g.c());
1172
1173                    // must not get here because decrypted data does
1174                    // not represent valid PKCS8 encoding
1175                    fail(algName[i][0] + ", " + algName[i][1]);
1176                } catch (InvalidKeySpecException ok) {
1177                }
1178
1179                performed = true;
1180            } catch (TestDataGenerator.AllowedFailure allowedFailure) {
1181            } catch (NoSuchAlgorithmException allowedFailure) {
1182            }
1183        }
1184        assertTrue("Test not performed", performed);
1185    }
1186
1187    public final void testGetKeySpecKey01() {
1188        boolean performed = false;
1189        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
1190            try {
1191                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
1192                        EncryptedPrivateKeyInfoData.algName0[i][0],
1193                        EncryptedPrivateKeyInfoData.encryptedData);
1194
1195                try {
1196
1197                    // check that method under test throws NPE
1198                    epki.getKeySpec((Key) null);
1199                    fail(getName() + "NullPointerException has not been thrown");
1200
1201                } catch (NullPointerException ok) {
1202                } catch (InvalidKeyException e) {
1203                    fail(getName() + "Unexpected exception: " + e);
1204                }
1205
1206                performed = true;
1207            } catch (NoSuchAlgorithmException allowedFailure) {
1208            }
1209        }
1210        assertTrue("Test not performed", performed);
1211    }
1212
1213    /**
1214     * Encrypted data contains valid PKCS8 key info encoding
1215     */
1216    public final void test_ROUNDTRIP_GetKeySpecKey01() {
1217        boolean performed = false;
1218        for (int i = 0; i < algName.length; i++) {
1219            try {
1220                // generate test data
1221                TestDataGenerator g = new TestDataGenerator(algName[i][0],
1222                        algName[i][1], privateKeyInfo, null);
1223
1224                // create test object
1225                EncryptedPrivateKeyInfo epki;
1226                if (g.ap() == null) {
1227                    epki = new EncryptedPrivateKeyInfo(algName[i][0], g.ct());
1228                } else {
1229                    epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
1230                }
1231
1232                try {
1233                    PKCS8EncodedKeySpec eks = epki
1234                            .getKeySpec(g.pubK() == null ? g.k() : g.pubK());
1235
1236                    if (!Arrays.equals(privateKeyInfo, eks.getEncoded())) {
1237                        fail(algName[i][0] + " != " + algName[i][1]);
1238                    }
1239                } catch (InvalidKeyException e) {
1240                    fail(algName[i][0] + ", " + algName[i][1] + ": " + e);
1241                }
1242
1243                performed = true;
1244            } catch (TestDataGenerator.AllowedFailure allowedFailure) {
1245            } catch (NoSuchAlgorithmException allowedFailure) {
1246            }
1247        }
1248        assertTrue("Test not performed", performed);
1249    }
1250
1251    /**
1252     * Encrypted data contains invalid PKCS8 key info encoding
1253     */
1254    public final void test_ROUNDTRIP_GetKeySpecKey02() {
1255        boolean performed = false;
1256        for (int i = 0; i < algName.length; i++) {
1257            try {
1258                // generate test data
1259                TestDataGenerator g = new TestDataGenerator(algName[i][0],
1260                        algName[i][1], privateKeyInfoDamaged, null);
1261
1262                // create test object
1263                EncryptedPrivateKeyInfo epki;
1264                if (g.ap() == null) {
1265                    epki = new EncryptedPrivateKeyInfo(algName[i][0], g.ct());
1266                } else {
1267                    epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
1268                }
1269
1270                try {
1271                    epki.getKeySpec(g.pubK() == null ? g.k() : g.pubK());
1272                    fail(algName[i][0] + ", " + algName[i][1]);
1273                } catch (InvalidKeyException e) {
1274                }
1275
1276                performed = true;
1277            } catch (TestDataGenerator.AllowedFailure allowedFailure) {
1278            } catch (NoSuchAlgorithmException allowedFailure) {
1279            }
1280        }
1281        assertTrue("Test not performed", performed);
1282    }
1283
1284    public final void testGetKeySpecKeyString01() throws Exception {
1285        boolean performed = false;
1286        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
1287            try {
1288                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
1289                        EncryptedPrivateKeyInfoData.algName0[i][0],
1290                        EncryptedPrivateKeyInfoData.encryptedData);
1291
1292                try {
1293                    // check that method under test throws NPE
1294                    epki.getKeySpec((Key) null, "SomeProviderName");
1295                    fail(getName() + "NullPointerException has not been thrown");
1296
1297                } catch (NullPointerException ok) {
1298                }
1299
1300                try {
1301                    epki.getKeySpec(new Key() {
1302                        public String getAlgorithm() {
1303                            return "alg";
1304                        }
1305
1306                        public String getFormat() {
1307                            return "fmt";
1308                        }
1309
1310                        public byte[] getEncoded() {
1311                            return new byte[] {};
1312                        }
1313                    }, "StrangeProviderName");
1314                    fail(getName() + "NoSuchProviderException has not been thrown");
1315                } catch (NoSuchProviderException ok) {
1316                    //expected
1317                }
1318
1319                try {
1320
1321                    // check that method under test throws NPE
1322                    epki.getKeySpec(new Key() {
1323                        public String getAlgorithm() {
1324                            return "alg";
1325                        }
1326
1327                        public String getFormat() {
1328                            return "fmt";
1329                        }
1330
1331                        public byte[] getEncoded() {
1332                            return new byte[] {};
1333                        }
1334                    }, (String) null);
1335
1336                    fail(getName() + "NullPointerException has not been thrown");
1337
1338                } catch (NullPointerException ok) {
1339                }
1340
1341                performed = true;
1342            } catch (NoSuchAlgorithmException allowedFailure) {
1343            }
1344        }
1345        assertTrue("Test not performed", performed);
1346    }
1347
1348    /**
1349     * Encrypted data contains valid PKCS8 key info encoding
1350     */
1351    public final void test_ROUNDTRIP_GetKeySpecKeyString01() throws Exception {
1352        boolean performed = false;
1353        for (int i = 0; i < algName.length; i++) {
1354            for (int l = 0; l < provider.length; l++) {
1355                if (provider[l] == null) {
1356                    continue;
1357                }
1358                TestDataGenerator g;
1359                try {
1360                    // generate test data
1361                    g = new TestDataGenerator(algName[i][0], algName[i][1],
1362                            privateKeyInfo, provider[l]);
1363                } catch (TestDataGenerator.AllowedFailure allowedFailure) {
1364                    continue;
1365                }
1366
1367                try {
1368                    // create test object
1369                    EncryptedPrivateKeyInfo epki;
1370                    if (g.ap() == null) {
1371                        epki = new EncryptedPrivateKeyInfo(algName[i][0], g
1372                                .ct());
1373                    } else {
1374                        epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
1375                    }
1376                    try {
1377
1378                        PKCS8EncodedKeySpec eks = epki.getKeySpec(
1379                                g.pubK() == null ? g.k() : g.pubK(),
1380                                provider[l].getName());
1381
1382                        if (!Arrays.equals(privateKeyInfo, eks.getEncoded())) {
1383                            fail(algName[i][0] + " != " + algName[i][1]);
1384                        }
1385                    } catch (InvalidKeyException e) {
1386                        fail(algName[i][0] + ", " + algName[i][1] + ": " + e);
1387                    }
1388
1389                    performed = true;
1390                } catch (NoSuchAlgorithmException allowedFailure) {
1391                }
1392            }
1393        }
1394        assertTrue("Test not performed", performed);
1395    }
1396
1397    /**
1398     * Encrypted data contains invalid PKCS8 key info encoding
1399     */
1400    public final void test_ROUNDTRIP_GetKeySpecKeyString02() throws Exception {
1401        boolean performed = false;
1402        for (int i = 0; i < algName.length; i++) {
1403            for (int l = 0; l < provider.length; l++) {
1404                if (provider[l] == null) {
1405                    continue;
1406                }
1407                TestDataGenerator g;
1408                try {
1409                    // generate test data
1410                    g = new TestDataGenerator(algName[i][0], algName[i][1],
1411                            privateKeyInfoDamaged, provider[l]);
1412                } catch (TestDataGenerator.AllowedFailure allowedFailure) {
1413                    continue;
1414                }
1415
1416                try {
1417                    // create test object
1418                    EncryptedPrivateKeyInfo epki;
1419                    if (g.ap() == null) {
1420                        epki = new EncryptedPrivateKeyInfo(algName[i][0], g
1421                                .ct());
1422                    } else {
1423                        epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
1424                    }
1425
1426                    try {
1427
1428                        epki.getKeySpec(g.pubK() == null ? g.k() : g.pubK(),
1429                                provider[l].getName());
1430
1431                        fail(algName[i][0] + ", " + algName[i][1]);
1432
1433                    } catch (InvalidKeyException e) {
1434                    }
1435
1436                    performed = true;
1437                } catch (NoSuchAlgorithmException allowedFailure) {
1438                }
1439            }
1440        }
1441        assertTrue("Test not performed", performed);
1442    }
1443
1444    public final void testGetKeySpecKeyProvider01() throws Exception {
1445        boolean performed = false;
1446
1447        for (int i = 0; i < EncryptedPrivateKeyInfoData.algName0.length; i++) {
1448            try {
1449                EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo(
1450                        EncryptedPrivateKeyInfoData.algName0[i][0],
1451                        EncryptedPrivateKeyInfoData.encryptedData);
1452
1453                try {
1454
1455                    // check that method under test throws NPE
1456                    epki.getKeySpec((Key) null, (Provider) null);
1457                    fail(getName() + "NullPointerException has not been thrown");
1458                } catch (NullPointerException ok) {
1459                }
1460
1461                try {
1462
1463                    // check that method under test throws NPE
1464                    epki.getKeySpec(new Key() {
1465                        public String getAlgorithm() {
1466                            return "alg";
1467                        }
1468
1469                        public String getFormat() {
1470                            return "fmt";
1471                        }
1472
1473                        public byte[] getEncoded() {
1474                            return new byte[] {};
1475                        }
1476                    }, (Provider) null);
1477
1478                    fail(getName() + "NullPointerException has not been thrown");
1479                } catch (NullPointerException ok) {
1480                }
1481
1482                performed = true;
1483            } catch (NoSuchAlgorithmException allowedFailure) {
1484            }
1485        }
1486        assertTrue("Test not performed", performed);
1487    }
1488
1489    /**
1490     * Encrypted data contains valid PKCS8 key info encoding
1491     */
1492    public final void test_ROUNDTRIP_GetKeySpecKeyProvider01() {
1493        boolean performed = false;
1494
1495        for (int i = 0; i < algName.length; i++) {
1496            for (int l = 0; l < provider.length; l++) {
1497                if (provider[l] == null) {
1498                    continue;
1499                }
1500                TestDataGenerator g;
1501                try {
1502                    // generate test data
1503                    g = new TestDataGenerator(algName[i][0], algName[i][1],
1504                            privateKeyInfo, provider[l]);
1505                } catch (TestDataGenerator.AllowedFailure allowedFailure) {
1506                    continue;
1507                }
1508                try {
1509                    // create test object
1510                    EncryptedPrivateKeyInfo epki;
1511                    if (g.ap() == null) {
1512                        epki = new EncryptedPrivateKeyInfo(algName[i][0], g
1513                                .ct());
1514                    } else {
1515                        epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
1516                    }
1517                    try {
1518
1519                        PKCS8EncodedKeySpec eks = epki.getKeySpec(
1520                                g.pubK() == null ? g.k() : g.pubK(),
1521                                provider[l]);
1522
1523                        if (!Arrays.equals(privateKeyInfo, eks.getEncoded())) {
1524                            fail(algName[i][0] + " != " + algName[i][1]);
1525                        }
1526                    } catch (InvalidKeyException e) {
1527                        fail(algName[i][0] + ", " + algName[i][1] + ": " + e);
1528                    }
1529                    performed = true;
1530
1531                } catch (NoSuchAlgorithmException allowedFailure) {
1532                }
1533            }
1534        }
1535        assertTrue("Test not performed", performed);
1536    }
1537
1538    /**
1539     * Encrypted data contains invalid PKCS8 key info encoding
1540     */
1541    public final void test_ROUNDTRIP_GetKeySpecKeyProvider02() {
1542        boolean performed = false;
1543
1544        for (int i = 0; i < algName.length; i++) {
1545            for (int l = 0; l < provider.length; l++) {
1546                if (provider[l] == null) {
1547                    continue;
1548                }
1549                TestDataGenerator g;
1550                try {
1551                    // generate test data
1552                    g = new TestDataGenerator(algName[i][0], algName[i][1],
1553                            privateKeyInfoDamaged, provider[l]);
1554                } catch (TestDataGenerator.AllowedFailure allowedFailure) {
1555                    continue;
1556                }
1557
1558                try {
1559                    // create test object
1560                    EncryptedPrivateKeyInfo epki;
1561                    if (g.ap() == null) {
1562                        epki = new EncryptedPrivateKeyInfo(algName[i][0], g
1563                                .ct());
1564                    } else {
1565                        epki = new EncryptedPrivateKeyInfo(g.ap(), g.ct());
1566                    }
1567                    try {
1568
1569                        epki.getKeySpec(g.pubK() == null ? g.k() : g.pubK(),
1570                                provider[l]);
1571
1572                        fail(algName[i][0] + ", " + algName[i][1]);
1573
1574                    } catch (InvalidKeyException e) {
1575                    }
1576                    performed = true;
1577                } catch (NoSuchAlgorithmException allowedFailure) {
1578                }
1579            }
1580        }
1581        assertTrue("Test not performed", performed);
1582    }
1583
1584    public static class TestDataGenerator {
1585
1586        public static class AllowedFailure extends Exception {
1587            AllowedFailure(String msg) {
1588                super(msg);
1589            }
1590        }
1591
1592        private Cipher c = null;
1593
1594        private Key k = null, pubK = null;
1595
1596        private AlgorithmParameters ap = null;
1597
1598        byte[] ct;
1599
1600        public TestDataGenerator(String algName, String transformation,
1601                byte[] privateKeyInfo, Provider provider) throws AllowedFailure {
1602            try {
1603                c = (provider == null) ? Cipher
1604                        .getInstance(transformation != null ? transformation
1605                                : algName) : Cipher.getInstance(
1606                        transformation != null ? transformation : algName,
1607                        provider);
1608            } catch (NoSuchAlgorithmException e) {
1609                throw new AllowedFailure(e.getMessage());
1610            } catch (NoSuchPaddingException e) {
1611                throw new AllowedFailure(e.getMessage());
1612            }
1613
1614            try {
1615                KeyGenerator kg = (provider == null) ? KeyGenerator
1616                        .getInstance(algName) : KeyGenerator.getInstance(
1617                        algName, provider);
1618                k = kg.generateKey();
1619            } catch (NoSuchAlgorithmException e) {
1620            }
1621
1622            if (k == null) {
1623                try {
1624                    KeyPairGenerator kpg = (provider == null) ? KeyPairGenerator
1625                            .getInstance(algName)
1626                            : KeyPairGenerator.getInstance(algName, provider);
1627                    KeyPair kp = kpg.genKeyPair();
1628                    k = kp.getPrivate();
1629                    pubK = kp.getPublic();
1630                } catch (NoSuchAlgorithmException e) {
1631                }
1632            }
1633
1634            PBEParameterSpec pbeParamSpec = null;
1635            if (k == null) {
1636                try {
1637                    pbeParamSpec = new PBEParameterSpec(new byte[] { 1, 2, 3,
1638                            4, 5, 6, 7, 8 }, 10);
1639                    SecretKeyFactory skf = (provider == null) ? SecretKeyFactory
1640                            .getInstance(algName)
1641                            : SecretKeyFactory.getInstance(algName, provider);
1642                    PBEKeySpec ks = new PBEKeySpec("12345678".toCharArray());
1643                    try {
1644                        k = skf.generateSecret(ks);
1645                    } catch (InvalidKeySpecException e) {
1646                        throw new AllowedFailure(e.getMessage());
1647                    }
1648
1649                } catch (NoSuchAlgorithmException e) {
1650                    throw new AllowedFailure(e.getMessage());
1651                }
1652            }
1653
1654            try {
1655                if (pbeParamSpec == null) {
1656                    c.init(Cipher.ENCRYPT_MODE, k);
1657                } else {
1658                    c.init(Cipher.ENCRYPT_MODE, k, pbeParamSpec);
1659                }
1660            } catch (InvalidKeyException e) {
1661                throw new AllowedFailure(e.getMessage());
1662            } catch (SecurityException e) {
1663                throw new AllowedFailure(e.getMessage());
1664            } catch (InvalidAlgorithmParameterException e) {
1665                throw new AllowedFailure(e.getMessage());
1666            }
1667
1668            ap = c.getParameters();
1669
1670            try {
1671                ct = c.doFinal(privateKeyInfo);
1672            } catch (IllegalStateException e) {
1673                throw new AllowedFailure(e.getMessage());
1674            } catch (IllegalBlockSizeException e) {
1675                throw new AllowedFailure(e.getMessage());
1676            } catch (BadPaddingException e) {
1677                throw new AllowedFailure(e.getMessage());
1678            } catch (RuntimeException e) {
1679                throw new AllowedFailure(e.getMessage());
1680            }
1681
1682            try {
1683                // try to convert pbeParamSpec->ap
1684                if (pbeParamSpec != null) {
1685                    try {
1686                        ap = (provider == null) ? AlgorithmParameters
1687                                .getInstance(algName) : AlgorithmParameters
1688                                .getInstance(algName, provider);
1689                        ap.init(pbeParamSpec);
1690                        pbeParamSpec = null;
1691                    } catch (NoSuchAlgorithmException e) {
1692                        // couldn't convert
1693                        throw new AllowedFailure(e.getMessage());
1694                    } catch (InvalidParameterSpecException e) {
1695                        // couldn't convert
1696                        throw new AllowedFailure(e.getMessage());
1697                    }
1698                }
1699
1700                if (ap == null) {
1701                    c.init(Cipher.DECRYPT_MODE, pubK == null ? k : pubK);
1702                } else {
1703                    c.init(Cipher.DECRYPT_MODE, pubK == null ? k : pubK, ap);
1704                }
1705
1706            } catch (InvalidKeyException e) {
1707                throw new AllowedFailure(e.getMessage());
1708            } catch (SecurityException e) {
1709                throw new AllowedFailure(e.getMessage());
1710            } catch (InvalidAlgorithmParameterException e) {
1711                throw new AllowedFailure(e.getMessage());
1712            }
1713        }
1714
1715        public Key k() {
1716            return k;
1717        }
1718
1719        public Key pubK() {
1720            return pubK;
1721        }
1722
1723        public Cipher c() {
1724            return c;
1725        }
1726
1727        public byte[] ct() {
1728            return ct;
1729        }
1730
1731        public AlgorithmParameters ap() {
1732            return ap;
1733        }
1734    }
1735
1736    // valid PrivateKeyInfo encoding
1737    private static final byte[] privateKeyInfo = { (byte) 0x30, (byte) 0x82,
1738            (byte) 0x02, (byte) 0x77, (byte) 0x02, (byte) 0x01, (byte) 0x00,
1739            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
1740            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
1741            (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00,
1742            (byte) 0x04, (byte) 0x82, (byte) 0x02, (byte) 0x61, (byte) 0x30,
1743            (byte) 0x82, (byte) 0x02, (byte) 0x5d, (byte) 0x02, (byte) 0x01,
1744            (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00,
1745            (byte) 0xb2, (byte) 0x4a, (byte) 0x9b, (byte) 0x5b, (byte) 0xba,
1746            (byte) 0x01, (byte) 0xc0, (byte) 0xcd, (byte) 0x65, (byte) 0x09,
1747            (byte) 0x63, (byte) 0x70, (byte) 0x0b, (byte) 0x5a, (byte) 0x1b,
1748            (byte) 0x92, (byte) 0x08, (byte) 0xf8, (byte) 0x55, (byte) 0x5e,
1749            (byte) 0x7c, (byte) 0x1b, (byte) 0x50, (byte) 0x17, (byte) 0xec,
1750            (byte) 0x44, (byte) 0x4c, (byte) 0x58, (byte) 0x42, (byte) 0x2b,
1751            (byte) 0x41, (byte) 0x09, (byte) 0x59, (byte) 0xf2, (byte) 0xe1,
1752            (byte) 0x5d, (byte) 0x43, (byte) 0x71, (byte) 0x4d, (byte) 0x92,
1753            (byte) 0x03, (byte) 0x1d, (byte) 0xb6, (byte) 0x6c, (byte) 0x7f,
1754            (byte) 0x5d, (byte) 0x48, (byte) 0xcd, (byte) 0x17, (byte) 0xec,
1755            (byte) 0xd7, (byte) 0x4c, (byte) 0x39, (byte) 0xb1, (byte) 0x7b,
1756            (byte) 0xe2, (byte) 0xbf, (byte) 0x96, (byte) 0x77, (byte) 0xbe,
1757            (byte) 0xd0, (byte) 0xa0, (byte) 0xf0, (byte) 0x2d, (byte) 0x6b,
1758            (byte) 0x24, (byte) 0xaa, (byte) 0x14, (byte) 0xba, (byte) 0x82,
1759            (byte) 0x79, (byte) 0x10, (byte) 0x9b, (byte) 0x16, (byte) 0x68,
1760            (byte) 0x47, (byte) 0x81, (byte) 0x54, (byte) 0xa2, (byte) 0xfa,
1761            (byte) 0x91, (byte) 0x9e, (byte) 0x0a, (byte) 0x2a, (byte) 0x53,
1762            (byte) 0xa6, (byte) 0xe7, (byte) 0x9e, (byte) 0x7d, (byte) 0x29,
1763            (byte) 0x33, (byte) 0xd8, (byte) 0x05, (byte) 0xfc, (byte) 0x02,
1764            (byte) 0x3f, (byte) 0xbd, (byte) 0xc7, (byte) 0x6e, (byte) 0xed,
1765            (byte) 0xaa, (byte) 0x30, (byte) 0x6c, (byte) 0x5f, (byte) 0x52,
1766            (byte) 0xed, (byte) 0x35, (byte) 0x65, (byte) 0x4b, (byte) 0x0e,
1767            (byte) 0xc8, (byte) 0xa7, (byte) 0x12, (byte) 0x10, (byte) 0x56,
1768            (byte) 0x37, (byte) 0xaf, (byte) 0x11, (byte) 0xfa, (byte) 0x21,
1769            (byte) 0x0e, (byte) 0x99, (byte) 0xff, (byte) 0xfa, (byte) 0x8c,
1770            (byte) 0x65, (byte) 0x8e, (byte) 0x6d, (byte) 0x02, (byte) 0x03,
1771            (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81,
1772            (byte) 0x80, (byte) 0x78, (byte) 0x41, (byte) 0x72, (byte) 0x40,
1773            (byte) 0x90, (byte) 0x59, (byte) 0x96, (byte) 0x5d, (byte) 0xf3,
1774            (byte) 0x84, (byte) 0x3d, (byte) 0x99, (byte) 0xd9, (byte) 0x4e,
1775            (byte) 0x51, (byte) 0xc2, (byte) 0x52, (byte) 0x62, (byte) 0x8d,
1776            (byte) 0xd2, (byte) 0x49, (byte) 0x0b, (byte) 0x73, (byte) 0x1e,
1777            (byte) 0x6f, (byte) 0xb2, (byte) 0x31, (byte) 0x7c, (byte) 0x66,
1778            (byte) 0x45, (byte) 0x1e, (byte) 0x7c, (byte) 0xdc, (byte) 0x3a,
1779            (byte) 0xc2, (byte) 0x5f, (byte) 0x51, (byte) 0x9a, (byte) 0x1e,
1780            (byte) 0xa4, (byte) 0x19, (byte) 0x8d, (byte) 0xf4, (byte) 0xf9,
1781            (byte) 0x81, (byte) 0x7e, (byte) 0xbe, (byte) 0x17, (byte) 0xf7,
1782            (byte) 0xc7, (byte) 0x3c, (byte) 0x00, (byte) 0xa1, (byte) 0xf9,
1783            (byte) 0x60, (byte) 0x82, (byte) 0x34, (byte) 0x8f, (byte) 0x9c,
1784            (byte) 0xfd, (byte) 0x0b, (byte) 0x63, (byte) 0x42, (byte) 0x1b,
1785            (byte) 0x7f, (byte) 0x45, (byte) 0xf1, (byte) 0x31, (byte) 0xc3,
1786            (byte) 0x63, (byte) 0x47, (byte) 0x5c, (byte) 0xc1, (byte) 0xb2,
1787            (byte) 0x5f, (byte) 0x57, (byte) 0xee, (byte) 0x02, (byte) 0x9f,
1788            (byte) 0x5e, (byte) 0x08, (byte) 0x48, (byte) 0xba, (byte) 0x74,
1789            (byte) 0xba, (byte) 0x81, (byte) 0xb7, (byte) 0x30, (byte) 0xac,
1790            (byte) 0x4c, (byte) 0x01, (byte) 0x35, (byte) 0xce, (byte) 0x46,
1791            (byte) 0x47, (byte) 0x8c, (byte) 0xe4, (byte) 0x62, (byte) 0x36,
1792            (byte) 0x1a, (byte) 0x65, (byte) 0x0e, (byte) 0x33, (byte) 0x56,
1793            (byte) 0xf9, (byte) 0xb7, (byte) 0xa0, (byte) 0xc4, (byte) 0xb6,
1794            (byte) 0x82, (byte) 0x55, (byte) 0x7d, (byte) 0x36, (byte) 0x55,
1795            (byte) 0xc0, (byte) 0x52, (byte) 0x5e, (byte) 0x35, (byte) 0x54,
1796            (byte) 0xbd, (byte) 0x97, (byte) 0x01, (byte) 0x00, (byte) 0xbf,
1797            (byte) 0x10, (byte) 0xdc, (byte) 0x1b, (byte) 0x51, (byte) 0x02,
1798            (byte) 0x41, (byte) 0x00, (byte) 0xe7, (byte) 0x68, (byte) 0x03,
1799            (byte) 0x3e, (byte) 0x21, (byte) 0x64, (byte) 0x68, (byte) 0x24,
1800            (byte) 0x7b, (byte) 0xd0, (byte) 0x31, (byte) 0xa0, (byte) 0xa2,
1801            (byte) 0xd9, (byte) 0x87, (byte) 0x6d, (byte) 0x79, (byte) 0x81,
1802            (byte) 0x8f, (byte) 0x8f, (byte) 0x2d, (byte) 0x7a, (byte) 0x95,
1803            (byte) 0x2e, (byte) 0x55, (byte) 0x9f, (byte) 0xd7, (byte) 0x86,
1804            (byte) 0x29, (byte) 0x93, (byte) 0xbd, (byte) 0x04, (byte) 0x7e,
1805            (byte) 0x4f, (byte) 0xdb, (byte) 0x56, (byte) 0xf1, (byte) 0x75,
1806            (byte) 0xd0, (byte) 0x4b, (byte) 0x00, (byte) 0x3a, (byte) 0xe0,
1807            (byte) 0x26, (byte) 0xf6, (byte) 0xab, (byte) 0x9e, (byte) 0x0b,
1808            (byte) 0x2a, (byte) 0xf4, (byte) 0xa8, (byte) 0xd7, (byte) 0xff,
1809            (byte) 0xbe, (byte) 0x01, (byte) 0xeb, (byte) 0x9b, (byte) 0x81,
1810            (byte) 0xc7, (byte) 0x5f, (byte) 0x02, (byte) 0x73, (byte) 0xe1,
1811            (byte) 0x2b, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xc5,
1812            (byte) 0x3d, (byte) 0x78, (byte) 0xab, (byte) 0xe6, (byte) 0xab,
1813            (byte) 0x3e, (byte) 0x29, (byte) 0xfd, (byte) 0x98, (byte) 0xd0,
1814            (byte) 0xa4, (byte) 0x3e, (byte) 0x58, (byte) 0xee, (byte) 0x48,
1815            (byte) 0x45, (byte) 0xa3, (byte) 0x66, (byte) 0xac, (byte) 0xe9,
1816            (byte) 0x4d, (byte) 0xbd, (byte) 0x60, (byte) 0xea, (byte) 0x24,
1817            (byte) 0xff, (byte) 0xed, (byte) 0x0c, (byte) 0x67, (byte) 0xc5,
1818            (byte) 0xfd, (byte) 0x36, (byte) 0x28, (byte) 0xea, (byte) 0x74,
1819            (byte) 0x88, (byte) 0xd1, (byte) 0xd1, (byte) 0xad, (byte) 0x58,
1820            (byte) 0xd7, (byte) 0xf0, (byte) 0x67, (byte) 0x20, (byte) 0xc1,
1821            (byte) 0xe3, (byte) 0xb3, (byte) 0xdb, (byte) 0x52, (byte) 0xad,
1822            (byte) 0xf3, (byte) 0xc4, (byte) 0x21, (byte) 0xd8, (byte) 0x8c,
1823            (byte) 0x4c, (byte) 0x41, (byte) 0x27, (byte) 0xdb, (byte) 0xd0,
1824            (byte) 0x35, (byte) 0x92, (byte) 0xc7, (byte) 0x02, (byte) 0x41,
1825            (byte) 0x00, (byte) 0xe0, (byte) 0x99, (byte) 0x42, (byte) 0xb4,
1826            (byte) 0x76, (byte) 0x02, (byte) 0x97, (byte) 0x55, (byte) 0xf9,
1827            (byte) 0xda, (byte) 0x3b, (byte) 0xa0, (byte) 0xd7, (byte) 0x0e,
1828            (byte) 0xdc, (byte) 0xf4, (byte) 0x33, (byte) 0x7f, (byte) 0xbd,
1829            (byte) 0xcf, (byte) 0xd0, (byte) 0xeb, (byte) 0x6e, (byte) 0x89,
1830            (byte) 0xf7, (byte) 0x4f, (byte) 0x5a, (byte) 0x07, (byte) 0x7c,
1831            (byte) 0xa9, (byte) 0x49, (byte) 0x47, (byte) 0x68, (byte) 0x35,
1832            (byte) 0xa8, (byte) 0x05, (byte) 0x3d, (byte) 0xfd, (byte) 0x04,
1833            (byte) 0x7b, (byte) 0x17, (byte) 0x31, (byte) 0x0d, (byte) 0xc8,
1834            (byte) 0xa3, (byte) 0x98, (byte) 0x34, (byte) 0xa0, (byte) 0x50,
1835            (byte) 0x44, (byte) 0x00, (byte) 0xf1, (byte) 0x0c, (byte) 0xe6,
1836            (byte) 0xe5, (byte) 0xc4, (byte) 0x41, (byte) 0x3d, (byte) 0xf8,
1837            (byte) 0x3d, (byte) 0x4e, (byte) 0x0b, (byte) 0x1c, (byte) 0xdb,
1838            (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0x82, (byte) 0x9b,
1839            (byte) 0x8a, (byte) 0xfd, (byte) 0xa1, (byte) 0x98, (byte) 0x41,
1840            (byte) 0x68, (byte) 0xc2, (byte) 0xd1, (byte) 0xdf, (byte) 0x4e,
1841            (byte) 0xf3, (byte) 0x2e, (byte) 0x26, (byte) 0x53, (byte) 0x5b,
1842            (byte) 0x31, (byte) 0xb1, (byte) 0x7a, (byte) 0xcc, (byte) 0x5e,
1843            (byte) 0xbb, (byte) 0x09, (byte) 0xa2, (byte) 0xe2, (byte) 0x6f,
1844            (byte) 0x4a, (byte) 0x04, (byte) 0x0d, (byte) 0xef, (byte) 0x90,
1845            (byte) 0x15, (byte) 0xbe, (byte) 0x10, (byte) 0x4a, (byte) 0xac,
1846            (byte) 0x92, (byte) 0xeb, (byte) 0xda, (byte) 0x72, (byte) 0xdb,
1847            (byte) 0x43, (byte) 0x08, (byte) 0xb7, (byte) 0x2b, (byte) 0x4c,
1848            (byte) 0xe1, (byte) 0xbb, (byte) 0x58, (byte) 0xcb, (byte) 0x71,
1849            (byte) 0x80, (byte) 0xad, (byte) 0xbc, (byte) 0xdc, (byte) 0x62,
1850            (byte) 0x5e, (byte) 0x3e, (byte) 0xcb, (byte) 0x92, (byte) 0xda,
1851            (byte) 0xf6, (byte) 0xdf, (byte) 0x02, (byte) 0x40, (byte) 0x4d,
1852            (byte) 0x81, (byte) 0x90, (byte) 0xc5, (byte) 0x77, (byte) 0x30,
1853            (byte) 0xb7, (byte) 0x29, (byte) 0x00, (byte) 0xa8, (byte) 0xf1,
1854            (byte) 0xb4, (byte) 0xae, (byte) 0x52, (byte) 0x63, (byte) 0x00,
1855            (byte) 0xb2, (byte) 0x2d, (byte) 0x3e, (byte) 0x7d, (byte) 0xd6,
1856            (byte) 0x4d, (byte) 0xf9, (byte) 0x8a, (byte) 0xc1, (byte) 0xb1,
1857            (byte) 0x98, (byte) 0x89, (byte) 0x52, (byte) 0x40, (byte) 0x14,
1858            (byte) 0x1b, (byte) 0x0e, (byte) 0x61, (byte) 0x8f, (byte) 0xf4,
1859            (byte) 0xbe, (byte) 0x59, (byte) 0x79, (byte) 0x79, (byte) 0x95,
1860            (byte) 0x19, (byte) 0x5c, (byte) 0x51, (byte) 0x08, (byte) 0x66,
1861            (byte) 0xc1, (byte) 0x42, (byte) 0x30, (byte) 0xb3, (byte) 0x7a,
1862            (byte) 0x86, (byte) 0x9f, (byte) 0x3e, (byte) 0xf5, (byte) 0x19,
1863            (byte) 0xa3, (byte) 0xae, (byte) 0x64, (byte) 0x69, (byte) 0x14,
1864            (byte) 0x07, (byte) 0x50, (byte) 0x97, };
1865
1866    // valid PrivateKeyInfo encoding (Damaged)
1867    private static final byte[] privateKeyInfoDamaged = { (byte) 0x30,
1868            (byte) 0x82, (byte) 0x02, (byte) 0x77, (byte) 0x02, (byte) 0x01,
1869            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
1870            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
1871            (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05,
1872            (byte) 0x00, (byte) 0x04, // private key octet str
1873            (byte) 0x82, (byte) 0x02, (byte) 0x62, // Damage: l=460->461
1874                                                   // (0x61->0x62)
1875            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5d, (byte) 0x02,
1876            (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
1877            (byte) 0x00, (byte) 0xb2, (byte) 0x4a, (byte) 0x9b, (byte) 0x5b,
1878            (byte) 0xba, (byte) 0x01, (byte) 0xc0, (byte) 0xcd, (byte) 0x65,
1879            (byte) 0x09, (byte) 0x63, (byte) 0x70, (byte) 0x0b, (byte) 0x5a,
1880            (byte) 0x1b, (byte) 0x92, (byte) 0x08, (byte) 0xf8, (byte) 0x55,
1881            (byte) 0x5e, (byte) 0x7c, (byte) 0x1b, (byte) 0x50, (byte) 0x17,
1882            (byte) 0xec, (byte) 0x44, (byte) 0x4c, (byte) 0x58, (byte) 0x42,
1883            (byte) 0x2b, (byte) 0x41, (byte) 0x09, (byte) 0x59, (byte) 0xf2,
1884            (byte) 0xe1, (byte) 0x5d, (byte) 0x43, (byte) 0x71, (byte) 0x4d,
1885            (byte) 0x92, (byte) 0x03, (byte) 0x1d, (byte) 0xb6, (byte) 0x6c,
1886            (byte) 0x7f, (byte) 0x5d, (byte) 0x48, (byte) 0xcd, (byte) 0x17,
1887            (byte) 0xec, (byte) 0xd7, (byte) 0x4c, (byte) 0x39, (byte) 0xb1,
1888            (byte) 0x7b, (byte) 0xe2, (byte) 0xbf, (byte) 0x96, (byte) 0x77,
1889            (byte) 0xbe, (byte) 0xd0, (byte) 0xa0, (byte) 0xf0, (byte) 0x2d,
1890            (byte) 0x6b, (byte) 0x24, (byte) 0xaa, (byte) 0x14, (byte) 0xba,
1891            (byte) 0x82, (byte) 0x79, (byte) 0x10, (byte) 0x9b, (byte) 0x16,
1892            (byte) 0x68, (byte) 0x47, (byte) 0x81, (byte) 0x54, (byte) 0xa2,
1893            (byte) 0xfa, (byte) 0x91, (byte) 0x9e, (byte) 0x0a, (byte) 0x2a,
1894            (byte) 0x53, (byte) 0xa6, (byte) 0xe7, (byte) 0x9e, (byte) 0x7d,
1895            (byte) 0x29, (byte) 0x33, (byte) 0xd8, (byte) 0x05, (byte) 0xfc,
1896            (byte) 0x02, (byte) 0x3f, (byte) 0xbd, (byte) 0xc7, (byte) 0x6e,
1897            (byte) 0xed, (byte) 0xaa, (byte) 0x30, (byte) 0x6c, (byte) 0x5f,
1898            (byte) 0x52, (byte) 0xed, (byte) 0x35, (byte) 0x65, (byte) 0x4b,
1899            (byte) 0x0e, (byte) 0xc8, (byte) 0xa7, (byte) 0x12, (byte) 0x10,
1900            (byte) 0x56, (byte) 0x37, (byte) 0xaf, (byte) 0x11, (byte) 0xfa,
1901            (byte) 0x21, (byte) 0x0e, (byte) 0x99, (byte) 0xff, (byte) 0xfa,
1902            (byte) 0x8c, (byte) 0x65, (byte) 0x8e, (byte) 0x6d, (byte) 0x02,
1903            (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x02,
1904            (byte) 0x81, (byte) 0x80, (byte) 0x78, (byte) 0x41, (byte) 0x72,
1905            (byte) 0x40, (byte) 0x90, (byte) 0x59, (byte) 0x96, (byte) 0x5d,
1906            (byte) 0xf3, (byte) 0x84, (byte) 0x3d, (byte) 0x99, (byte) 0xd9,
1907            (byte) 0x4e, (byte) 0x51, (byte) 0xc2, (byte) 0x52, (byte) 0x62,
1908            (byte) 0x8d, (byte) 0xd2, (byte) 0x49, (byte) 0x0b, (byte) 0x73,
1909            (byte) 0x1e, (byte) 0x6f, (byte) 0xb2, (byte) 0x31, (byte) 0x7c,
1910            (byte) 0x66, (byte) 0x45, (byte) 0x1e, (byte) 0x7c, (byte) 0xdc,
1911            (byte) 0x3a, (byte) 0xc2, (byte) 0x5f, (byte) 0x51, (byte) 0x9a,
1912            (byte) 0x1e, (byte) 0xa4, (byte) 0x19, (byte) 0x8d, (byte) 0xf4,
1913            (byte) 0xf9, (byte) 0x81, (byte) 0x7e, (byte) 0xbe, (byte) 0x17,
1914            (byte) 0xf7, (byte) 0xc7, (byte) 0x3c, (byte) 0x00, (byte) 0xa1,
1915            (byte) 0xf9, (byte) 0x60, (byte) 0x82, (byte) 0x34, (byte) 0x8f,
1916            (byte) 0x9c, (byte) 0xfd, (byte) 0x0b, (byte) 0x63, (byte) 0x42,
1917            (byte) 0x1b, (byte) 0x7f, (byte) 0x45, (byte) 0xf1, (byte) 0x31,
1918            (byte) 0xc3, (byte) 0x63, (byte) 0x47, (byte) 0x5c, (byte) 0xc1,
1919            (byte) 0xb2, (byte) 0x5f, (byte) 0x57, (byte) 0xee, (byte) 0x02,
1920            (byte) 0x9f, (byte) 0x5e, (byte) 0x08, (byte) 0x48, (byte) 0xba,
1921            (byte) 0x74, (byte) 0xba, (byte) 0x81, (byte) 0xb7, (byte) 0x30,
1922            (byte) 0xac, (byte) 0x4c, (byte) 0x01, (byte) 0x35, (byte) 0xce,
1923            (byte) 0x46, (byte) 0x47, (byte) 0x8c, (byte) 0xe4, (byte) 0x62,
1924            (byte) 0x36, (byte) 0x1a, (byte) 0x65, (byte) 0x0e, (byte) 0x33,
1925            (byte) 0x56, (byte) 0xf9, (byte) 0xb7, (byte) 0xa0, (byte) 0xc4,
1926            (byte) 0xb6, (byte) 0x82, (byte) 0x55, (byte) 0x7d, (byte) 0x36,
1927            (byte) 0x55, (byte) 0xc0, (byte) 0x52, (byte) 0x5e, (byte) 0x35,
1928            (byte) 0x54, (byte) 0xbd, (byte) 0x97, (byte) 0x01, (byte) 0x00,
1929            (byte) 0xbf, (byte) 0x10, (byte) 0xdc, (byte) 0x1b, (byte) 0x51,
1930            (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xe7, (byte) 0x68,
1931            (byte) 0x03, (byte) 0x3e, (byte) 0x21, (byte) 0x64, (byte) 0x68,
1932            (byte) 0x24, (byte) 0x7b, (byte) 0xd0, (byte) 0x31, (byte) 0xa0,
1933            (byte) 0xa2, (byte) 0xd9, (byte) 0x87, (byte) 0x6d, (byte) 0x79,
1934            (byte) 0x81, (byte) 0x8f, (byte) 0x8f, (byte) 0x2d, (byte) 0x7a,
1935            (byte) 0x95, (byte) 0x2e, (byte) 0x55, (byte) 0x9f, (byte) 0xd7,
1936            (byte) 0x86, (byte) 0x29, (byte) 0x93, (byte) 0xbd, (byte) 0x04,
1937            (byte) 0x7e, (byte) 0x4f, (byte) 0xdb, (byte) 0x56, (byte) 0xf1,
1938            (byte) 0x75, (byte) 0xd0, (byte) 0x4b, (byte) 0x00, (byte) 0x3a,
1939            (byte) 0xe0, (byte) 0x26, (byte) 0xf6, (byte) 0xab, (byte) 0x9e,
1940            (byte) 0x0b, (byte) 0x2a, (byte) 0xf4, (byte) 0xa8, (byte) 0xd7,
1941            (byte) 0xff, (byte) 0xbe, (byte) 0x01, (byte) 0xeb, (byte) 0x9b,
1942            (byte) 0x81, (byte) 0xc7, (byte) 0x5f, (byte) 0x02, (byte) 0x73,
1943            (byte) 0xe1, (byte) 0x2b, (byte) 0x02, (byte) 0x41, (byte) 0x00,
1944            (byte) 0xc5, (byte) 0x3d, (byte) 0x78, (byte) 0xab, (byte) 0xe6,
1945            (byte) 0xab, (byte) 0x3e, (byte) 0x29, (byte) 0xfd, // 88
1946            (byte) 0x98, (byte) 0xd0, (byte) 0xa4, (byte) 0x3e, (byte) 0x58,
1947            (byte) 0xee, (byte) 0x48, (byte) 0x45, (byte) 0xa3, (byte) 0x66,
1948            (byte) 0xac, (byte) 0xe9, (byte) 0x4d, (byte) 0xbd, (byte) 0x60,
1949            (byte) 0xea, (byte) 0x24, (byte) 0xff, (byte) 0xed, (byte) 0x0c,
1950            (byte) 0x67, (byte) 0xc5, (byte) 0xfd, (byte) 0x36, (byte) 0x28,
1951            (byte) 0xea, (byte) 0x74, (byte) 0x88, (byte) 0xd1, (byte) 0xd1,
1952            (byte) 0xad, (byte) 0x58, (byte) 0xd7, (byte) 0xf0, (byte) 0x67,
1953            (byte) 0x20, (byte) 0xc1, (byte) 0xe3, (byte) 0xb3, (byte) 0xdb,
1954            (byte) 0x52, (byte) 0xad, (byte) 0xf3, (byte) 0xc4, (byte) 0x21,
1955            (byte) 0xd8, (byte) 0x8c, (byte) 0x4c, (byte) 0x41, (byte) 0x27,
1956            (byte) 0xdb, (byte) 0xd0, (byte) 0x35, (byte) 0x92, (byte) 0xc7,
1957            (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xe0, (byte) 0x99,
1958            (byte) 0x42, (byte) 0xb4, (byte) 0x76, (byte) 0x02, (byte) 0x97,
1959            (byte) 0x55, (byte) 0xf9, (byte) 0xda, (byte) 0x3b, (byte) 0xa0,
1960            (byte) 0xd7, (byte) 0x0e, (byte) 0xdc, (byte) 0xf4, (byte) 0x33,
1961            (byte) 0x7f, (byte) 0xbd, (byte) 0xcf, (byte) 0xd0, (byte) 0xeb,
1962            (byte) 0x6e, (byte) 0x89, (byte) 0xf7, (byte) 0x4f, (byte) 0x5a,
1963            (byte) 0x07, (byte) 0x7c, (byte) 0xa9, (byte) 0x49, (byte) 0x47,
1964            (byte) 0x68, (byte) 0x35, (byte) 0xa8, (byte) 0x05, (byte) 0x3d,
1965            (byte) 0xfd, (byte) 0x04, (byte) 0x7b, (byte) 0x17, (byte) 0x31,
1966            (byte) 0x0d, (byte) 0xc8, (byte) 0xa3, (byte) 0x98, (byte) 0x34,
1967            (byte) 0xa0, (byte) 0x50, (byte) 0x44, (byte) 0x00, (byte) 0xf1,
1968            (byte) 0x0c, (byte) 0xe6, (byte) 0xe5, (byte) 0xc4, (byte) 0x41,
1969            (byte) 0x3d, (byte) 0xf8, (byte) 0x3d, (byte) 0x4e, (byte) 0x0b, // 118
1970            (byte) 0x1c, (byte) 0xdb, (byte) 0x02, (byte) 0x41, (byte) 0x00,
1971            (byte) 0x82, (byte) 0x9b, (byte) 0x8a, (byte) 0xfd, (byte) 0xa1,
1972            (byte) 0x98, (byte) 0x41, (byte) 0x68, (byte) 0xc2, (byte) 0xd1,
1973            (byte) 0xdf, (byte) 0x4e, (byte) 0xf3, (byte) 0x2e, (byte) 0x26,
1974            (byte) 0x53, (byte) 0x5b, (byte) 0x31, (byte) 0xb1, (byte) 0x7a,
1975            (byte) 0xcc, (byte) 0x5e, (byte) 0xbb, (byte) 0x09, (byte) 0xa2,
1976            (byte) 0xe2, (byte) 0x6f, (byte) 0x4a, (byte) 0x04, (byte) 0x0d,
1977            (byte) 0xef, (byte) 0x90, (byte) 0x15, (byte) 0xbe, (byte) 0x10,
1978            (byte) 0x4a, (byte) 0xac, (byte) 0x92, (byte) 0xeb, (byte) 0xda,
1979            (byte) 0x72, (byte) 0xdb, (byte) 0x43, (byte) 0x08, (byte) 0xb7,
1980            (byte) 0x2b, (byte) 0x4c, (byte) 0xe1, (byte) 0xbb, (byte) 0x58,
1981            (byte) 0xcb, (byte) 0x71, (byte) 0x80, (byte) 0xad, (byte) 0xbc,
1982            (byte) 0xdc, (byte) 0x62, (byte) 0x5e, (byte) 0x3e, (byte) 0xcb,
1983            (byte) 0x92, (byte) 0xda, (byte) 0xf6, (byte) 0xdf, (byte) 0x02,
1984            (byte) 0x40, (byte) 0x4d, (byte) 0x81, (byte) 0x90, (byte) 0xc5,
1985            (byte) 0x77, (byte) 0x30, (byte) 0xb7, (byte) 0x29, (byte) 0x00,
1986            (byte) 0xa8, (byte) 0xf1, (byte) 0xb4, (byte) 0xae, (byte) 0x52,
1987            (byte) 0x63, (byte) 0x00, (byte) 0xb2, // 140
1988            (byte) 0x2d, (byte) 0x3e, (byte) 0x7d, (byte) 0xd6, (byte) 0x4d,
1989            (byte) 0xf9, (byte) 0x8a, (byte) 0xc1, (byte) 0xb1, (byte) 0x98,
1990            (byte) 0x89, (byte) 0x52, (byte) 0x40, (byte) 0x14, (byte) 0x1b,
1991            (byte) 0x0e, (byte) 0x61, (byte) 0x8f, (byte) 0xf4, (byte) 0xbe,
1992            (byte) 0x59, (byte) 0x79, (byte) 0x79, (byte) 0x95, (byte) 0x19,
1993            (byte) 0x5c, (byte) 0x51, (byte) 0x08, (byte) 0x66, (byte) 0xc1,
1994            (byte) 0x42, (byte) 0x30, (byte) 0xb3, (byte) 0x7a, (byte) 0x86,
1995            (byte) 0x9f, (byte) 0x3e, (byte) 0xf5, (byte) 0x19, (byte) 0xa3, // 150
1996            (byte) 0xae, (byte) 0x64, (byte) 0x69, (byte) 0x14, (byte) 0x07,
1997            (byte) 0x50, (byte) 0x97, };
1998}
1999