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.security.tests.support.cert;
24
25import tests.support.resource.Support_Resources;
26
27import java.io.BufferedInputStream;
28import java.io.ByteArrayInputStream;
29import java.io.IOException;
30import java.math.BigInteger;
31import java.security.InvalidAlgorithmParameterException;
32import java.security.KeyStore;
33import java.security.NoSuchAlgorithmException;
34import java.security.cert.CertPath;
35import java.security.cert.CertPathBuilder;
36import java.security.cert.CertPathBuilderException;
37import java.security.cert.CertPathBuilderResult;
38import java.security.cert.CertPathParameters;
39import java.security.cert.CertPathValidatorException;
40import java.security.cert.CertStore;
41import java.security.cert.Certificate;
42import java.security.cert.CertificateException;
43import java.security.cert.CertificateFactory;
44import java.security.cert.CollectionCertStoreParameters;
45import java.security.cert.PKIXBuilderParameters;
46import java.security.cert.PKIXCertPathBuilderResult;
47import java.security.cert.PKIXCertPathChecker;
48import java.security.cert.PolicyNode;
49import java.security.cert.PolicyQualifierInfo;
50import java.security.cert.TrustAnchor;
51import java.security.cert.X509CertSelector;
52import java.security.cert.X509Certificate;
53import java.util.ArrayList;
54import java.util.Collection;
55import java.util.Collections;
56import java.util.HashSet;
57import java.util.Iterator;
58import java.util.List;
59import java.util.Set;
60
61/**
62 * java.security.cert test utilities
63 *
64 */
65public class TestUtils {
66    // Certificate type used during testing
67    private static final String certType = "X.509";
68    // Key store type used during testing
69    private static final String keyStoreType = "BKS";
70    // The file name prefix to load keystore from
71    private static final String keyStoreFileName = "test." + keyStoreType
72            + ".ks";
73    //
74    // The file name suffixes to load keystore from
75    //  *.ks1 - keystore containing untrusted certificates only
76    //  *.ks2 - keystore containing trusted certificates only
77    //  *.ks3 - keystore containing both trusted and untrusted certificates
78    //
79    public static final int UNTRUSTED = 1;
80    public static final int TRUSTED = 2;
81    public static final int TRUSTED_AND_UNTRUSTED = 3;
82    //
83    // Common passwords for all test keystores
84    //
85    private final static char[] storepass =
86        new char[] {'s','t','o','r','e','p','w','d'};
87
88    /**
89     * Creates <code>TrustAnchor</code> instance
90     * constructed using self signed test certificate
91     *
92     * @return <code>TrustAnchor</code> instance
93     */
94    public static TrustAnchor getTrustAnchor() {
95        CertificateFactory cf = null;
96        try {
97            cf = CertificateFactory.getInstance(certType);
98        } catch (CertificateException e) {
99            // requested cert type is not available in the
100            // default provider package or any of the other provider packages
101            // that were searched
102            throw new RuntimeException(e);
103        }
104        BufferedInputStream bis = null;
105        try {
106            bis = new BufferedInputStream(new ByteArrayInputStream(
107                    getEncodedX509Certificate()));
108            X509Certificate c1 = (X509Certificate)cf.generateCertificate(bis);
109
110            return new TrustAnchor(c1, null);
111        } catch (Exception e) {
112            // all failures are fatal
113            throw new RuntimeException(e);
114        } finally {
115            if (bis != null) {
116                try {
117                    bis.close() ;
118                } catch (IOException ign) {}
119            }
120        }
121    }
122
123    /**
124     * Creates <code>Set</code> of <code>TrustAnchor</code>s
125     * containing single element (self signed test certificate).
126     * @return Returns <code>Set</code> of <code>TrustAnchor</code>s
127     */
128    public static Set<TrustAnchor> getTrustAnchorSet() {
129        TrustAnchor ta = getTrustAnchor();
130        if (ta == null) {
131            return null;
132        }
133        HashSet<TrustAnchor> set = new HashSet<TrustAnchor>();
134        if (!set.add(ta)) {
135            throw new RuntimeException("Could not create trust anchor set");
136        }
137        return set;
138    }
139
140    /**
141     * Creates test <code>KeyStore</code> instance
142     *
143     * @param initialize
144     *  Do not initialize returned <code>KeyStore</code> if false
145     *
146     * @param testKeyStoreType
147     *  this parameter ignored if <code>initialize</code> is false;
148     *  The following types supported:<br>
149     *  1 - <code>KeyStore</code> with untrusted certificates only<br>
150     *  2 - <code>KeyStore</code> with trusted certificates only<br>
151     *  3 - <code>KeyStore</code> with both trusted and untrusted certificates
152     *
153     * @return Returns test <code>KeyStore</code> instance
154     */
155    public static KeyStore getKeyStore(boolean initialize,
156            int testKeyStoreType) {
157        BufferedInputStream bis = null;
158        try {
159            KeyStore ks = KeyStore.getInstance(keyStoreType);
160            if (initialize) {
161                String fileName = keyStoreFileName + testKeyStoreType;
162                ks.load(Support_Resources.getResourceStream(fileName),
163                        storepass);
164            }
165            return ks;
166        } catch (Exception e) {
167            throw new RuntimeException(e);
168        } finally {
169            if (initialize && bis != null) {
170                try {
171                    bis.close();
172                } catch (IOException ign) {}
173            }
174        }
175    }
176
177    /**
178     * Creates <code>List</code> of <code>CollectionCertStores</code>
179     *
180     * @return The list created
181     *
182     * @throws InvalidAlgorithmParameterException
183     * @throws NoSuchAlgorithmException
184     */
185    public static List<CertStore> getCollectionCertStoresList()
186        throws InvalidAlgorithmParameterException,
187               NoSuchAlgorithmException {
188        CertStore cs = CertStore.getInstance("Collection",
189                new CollectionCertStoreParameters());
190        ArrayList<CertStore> l = new ArrayList<CertStore>();
191        if (!l.add(cs)) {
192            throw new RuntimeException("Could not create cert stores list");
193        }
194        return l;
195    }
196
197    /**
198     * Creates stub implementation of the <code>PKIXCertPathChecker</code>
199     *
200     * @return Stub implementation of the <code>PKIXCertPathChecker</code>
201     */
202    public static PKIXCertPathChecker getTestCertPathChecker() {
203        // stub implementation for testing purposes only
204        return new PKIXCertPathChecker() {
205            private boolean forward = false;
206
207
208            @SuppressWarnings({"unused", "unchecked"})
209            public void check(Certificate arg0, Collection arg1)
210                    throws CertPathValidatorException {
211            }
212
213            public Set<String> getSupportedExtensions() {
214                return null;
215            }
216
217            @SuppressWarnings("unused")
218            public void init(boolean arg0) throws CertPathValidatorException {
219                forward = arg0;
220            }
221
222            public boolean isForwardCheckingSupported() {
223                // just to check this checker state
224                return forward;
225            }
226        };
227    }
228
229    /**
230     * Creates policy tree stub containing two <code>PolicyNode</code>s
231     * for testing purposes
232     *
233     * @return root <code>PolicyNode</code> of the policy tree
234     */
235    public static PolicyNode getPolicyTree() {
236        return new PolicyNode() {
237            final PolicyNode parent = this;
238            public int getDepth() {
239                // parent
240                return 0;
241            }
242
243            public boolean isCritical() {
244                return false;
245            }
246
247            public String getValidPolicy() {
248                return null;
249            }
250
251            public PolicyNode getParent() {
252                return null;
253            }
254
255            public Iterator<PolicyNode> getChildren() {
256                PolicyNode child = new PolicyNode() {
257                    public int getDepth() {
258                        // child
259                        return 1;
260                    }
261
262                    public boolean isCritical() {
263                        return false;
264                    }
265
266                    public String getValidPolicy() {
267                        return null;
268                    }
269
270                    public PolicyNode getParent() {
271                        return parent;
272                    }
273
274                    public Iterator<PolicyNode> getChildren() {
275                        return null;
276                    }
277
278                    public Set<String> getExpectedPolicies() {
279                        return null;
280                    }
281
282                    public Set<? extends PolicyQualifierInfo> getPolicyQualifiers() {
283                        return null;
284                    }
285                };
286                HashSet<PolicyNode> s = new HashSet<PolicyNode>();
287                s.add(child);
288                return s.iterator();
289            }
290
291            public Set<String> getExpectedPolicies() {
292                return null;
293            }
294
295            public Set<? extends PolicyQualifierInfo> getPolicyQualifiers() {
296                return null;
297            }
298        };
299    }
300    // X.509 encoded certificate
301    private static final String ENCODED_X509_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n"
302            + "MIIDHTCCAtsCBEFT72swCwYHKoZIzjgEAwUAMHQxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNOU08x\n"
303            + "FDASBgNVBAcTC05vdm9zaWJpcnNrMQ4wDAYDVQQKEwVJbnRlbDEVMBMGA1UECxMMRFJMIFNlY3Vy\n"
304            + "aXR5MRowGAYDVQQDExFWbGFkaW1pciBNb2xvdGtvdjAeFw0wNDA5MjQwOTU2NTlaFw0wNjA1MTcw\n"
305            + "OTU2NTlaMHQxCzAJBgNVBAYTAlJVMQwwCgYDVQQIEwNOU08xFDASBgNVBAcTC05vdm9zaWJpcnNr\n"
306            + "MQ4wDAYDVQQKEwVJbnRlbDEVMBMGA1UECxMMRFJMIFNlY3VyaXR5MRowGAYDVQQDExFWbGFkaW1p\n"
307            + "ciBNb2xvdGtvdjCCAbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3Ujzv\n"
308            + "RADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7\n"
309            + "qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8V\n"
310            + "IwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrU\n"
311            + "WU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEk\n"
312            + "O8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDiNmj9jgWu1ILYqYWcUhNN\n"
313            + "8CjjRitf80yWP/s/565wZz3anb2w72jum63mdShDko9eOOOd1hiVuiBnNhSL7D6JfIYBJvNXr1av\n"
314            + "Gw583BBv12OBgg0eAW/GRWBn2Ak2JjsoBc5x2c1HAEufakep7T6RoC+n3lqbKPKyHWVdfqQ9KTAL\n"
315            + "BgcqhkjOOAQDBQADLwAwLAIUaRS3C9dXcMbrOAhmidFBr7oMvH0CFEC3LUwfLJX5gY8P6uxpkPx3\n"
316            + "JDSM\n" + "-----END CERTIFICATE-----\n";
317
318    public static byte[] getEncodedX509Certificate() {
319        return ENCODED_X509_CERTIFICATE.getBytes();
320    }
321
322    /**
323     * Returns X.509 certificate encoding corresponding to version v1.
324     *
325     * Certificate encoding was created by hands according to X.509 Certificate
326     * ASN.1 notation. The certificate encoding has the following encoded
327     * field values:<br>
328     * - version: 1<br>
329     * - serialNumber: 5<br>
330     * - issuer: CN=Z<br>
331     * - notBefore: 13 Dec 1999 14:15:16<br>
332     * - notAfter: 01 Jan 2000 00:00:00<br>
333     * - subject: CN=Y<br>
334     *
335     * @return X.509 certificate encoding corresponding to version v1.
336     */
337    public static byte[] getX509Certificate_v1() {
338        return new byte[] {
339        // Certificate: SEQUENCE
340            0x30, 0x6B,
341
342            //
343            // TBSCertificate: SEQUENCE {
344            //
345            0x30, 0x5C,
346
347            // version: [0] EXPLICIT Version DEFAULT v1
348            (byte) 0xA0, 0x03, 0x02, 0x01, 0x00,
349
350            // serialNumber: CertificateSerialNumber
351            0x02, 0x01, 0x05,
352
353            // signature: AlgorithmIdentifier
354            0x30, 0x07, // SEQUENCE
355            0x06, 0x02, 0x03, 0x05,//OID
356            0x01, 0x01, 0x07, //ANY
357
358            //issuer: Name
359            0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
360            0x13, 0x01, 0x5A, // CN=Z
361
362            //validity: Validity
363            0x30, 0x1E, // SEQUENCE
364            // notBefore: UTCTime
365            0x17, 0x0D, 0x39, 0x39, 0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31,
366            0x35, 0x31, 0x36, 0x5A, // 13 Dec 1999 14:15:16
367            // notAfter:  UTCTime
368            0x17, 0x0D, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
369            0x30, 0x30, 0x30, 0x5A, // 01 Jan 2000 00:00:00
370
371            //subject: Name
372            0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
373            0x13, 0x01, 0x59, // CN=Y
374            //SubjectPublicKeyInfo  ::=  SEQUENCE  {
375            //    algorithm            AlgorithmIdentifier,
376            //    subjectPublicKey     BIT STRING  }
377            0x30, 0x0D, // SEQUENCE
378            0x30, 0x07, // SEQUENCE
379            0x06, 0x02, 0x03, 0x05,//OID
380            0x01, 0x01, 0x07, //ANY
381            0x03, 0x02, 0x00, 0x01, // subjectPublicKey
382
383            // issuerUniqueID - missed
384            // subjectUniqueID - missed
385            // extensions - missed
386
387            // } end TBSCertificate
388
389            //
390            // signatureAlgorithm: AlgorithmIdentifier
391            //
392            0x30, 0x07, // SEQUENCE
393            0x06, 0x02, 0x03, 0x05,//OID
394            0x01, 0x01, 0x07, //ANY
395
396            //
397            // signature: BIT STRING
398            //
399            0x03, 0x02, 0x00, 0x01 };
400    }
401
402    /**
403     * Returns X.509 certificate encoding corresponding to version v3.
404     *
405     * Certificate encoding was created by hands according to X.509 Certificate
406     * ASN.1 notation. The certificate encoding has the following encoded
407     * field values:<br>
408     * - version: 3<br>
409     * - serialNumber: 5<br>
410     * - issuer: CN=Z<br>
411     * - notBefore: 13 Dec 1999 14:15:16<br>
412     * - notAfter: 01 Jan 2000 00:00:00<br>
413     * - subject: CN=Y<br>
414     * - extensions:
415     *       1) AuthorityKeyIdentifier(OID=2.5.29.35): no values in it(empty sequence)
416     *
417     * @return X.509 certificate encoding corresponding to version v3.
418     */
419    public static byte[] getX509Certificate_v3() {
420        return new byte[] {
421        // Certificate: SEQUENCE
422            0x30, 0x7D,
423
424            //
425            // TBSCertificate: SEQUENCE {
426            //
427            0x30, 0x6E,
428
429            // version: [0] EXPLICIT Version DEFAULT v1
430            (byte) 0xA0, 0x03, 0x02, 0x01, 0x02,
431
432            // serialNumber: CertificateSerialNumber
433            0x02, 0x01, 0x05,
434
435            // signature: AlgorithmIdentifier
436            0x30, 0x07, // SEQUENCE
437            0x06, 0x02, 0x03, 0x05,//OID
438            0x01, 0x01, 0x07, //ANY
439
440            //issuer: Name
441            0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
442            0x13, 0x01, 0x5A, // CN=Z
443
444            //validity: Validity
445            0x30, 0x1E, // SEQUENCE
446            // notBefore: UTCTime
447            0x17, 0x0D, 0x39, 0x39, 0x31, 0x32, 0x31, 0x33, 0x31, 0x34, 0x31,
448            0x35, 0x31, 0x36, 0x5A, // 13 Dec 1999 14:15:16
449            // notAfter:  UTCTime
450            0x17, 0x0D, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
451            0x30, 0x30, 0x30, 0x5A, // 01 Jan 2000 00:00:00
452
453            //subject: Name
454            0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04, 0x03,
455            0x13, 0x01, 0x59, // CN=Y
456            //SubjectPublicKeyInfo  ::=  SEQUENCE  {
457            //    algorithm            AlgorithmIdentifier,
458            //    subjectPublicKey     BIT STRING  }
459            0x30, 0x0D, // SEQUENCE
460            0x30, 0x07, // SEQUENCE
461            0x06, 0x02, 0x03, 0x05,//OID
462            0x01, 0x01, 0x07, //ANY
463            0x03, 0x02, 0x00, 0x01, // subjectPublicKey
464
465            // issuerUniqueID - missed
466            // subjectUniqueID - missed
467            // extensions : [3]  EXPLICIT Extensions OPTIONAL
468            (byte) 0xA3, 0x10,
469            // Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
470            0x30, 0x0E,
471            // Extension  ::=  SEQUENCE  {
472            // extnID      OBJECT IDENTIFIER,
473            // critical    BOOLEAN DEFAULT FALSE,
474            // extnValue   OCTET STRING  }
475
476            // 1) AuthorityKeyIdentifier extension (see HARMONY-3384)
477            0x30, 0x0C,
478            0x06, 0x03, 0x55, 0x1D, 0x23, // OID = 2.5.29.35
479            0x01, 0x01, 0x00, // critical = FALSE
480            0x04, 0x02, 0x30, 0x00, // extnValue: MUST be empty sequence
481            // missed: keyIdentifier
482            // missed: authorityCertIssuer
483            // missed" authorityCertSerialNumber
484
485            // } end TBSCertificate
486
487            //
488            // signatureAlgorithm: AlgorithmIdentifier
489            //
490            0x30, 0x07, // SEQUENCE
491            0x06, 0x02, 0x03, 0x05,//OID
492            0x01, 0x01, 0x07, //ANY
493
494            //
495            // signature: BIT STRING
496            //
497            0x03, 0x02, 0x00, 0x01 };
498    }
499
500    /**
501     * Returns X.509 CRL encoding corresponding to version v1.
502     *
503     * CRL encoding was created by hands according to X.509 CRL ASN.1
504     * notation. The CRL encoding has the following encoded field values:<br>
505     * - version: 1<br>
506     * - issuer: CN=Z<br>
507     * - thisUpdate: 01 Jan 2001 01:02:03<br>
508     *
509     * @return X.509 CRL encoding corresponding to version v1.
510     */
511    public static byte[] getX509CRL_v1() {
512        return new byte[] {
513                //CertificateList: SEQUENCE
514                0x30, 0x35,
515
516                // TBSCertList: SEQUENCE
517                0x30, 0x27,
518                // Version: INTEGER OPTIONAL
519                // 0x02, 0x01, 0x01, - missed here cause it is v1
520                // signature: AlgorithmIdentifier
521                0x30, 0x06, // SEQUENCE
522                0x06, 0x01, 0x01, // OID
523                0x01, 0x01, 0x11, // ANY
524                // issuer: Name
525                0x30, 0x0C, 0x31, 0x0A, 0x30, 0x08, 0x06, 0x03, 0x55, 0x04,
526                0x03, 0x13, 0x01, 0x5A, // CN=Z
527                // thisUpdate: ChoiceOfTime
528                // GeneralizedTime: 01 Jan 2001 01:02:03
529                0x18, 0x0F, 0x32, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31,
530                0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x5A,
531
532                // nextUpdate - missed
533                // revokedCertificates - missed
534                // crlExtensions - missed
535
536                // signatureAlgorithm: AlgorithmIdentifier
537                0x30, 0x06, // SEQUENCE
538                0x06, 0x01, 0x01, //OID
539                0x01, 0x01, 0x11, //ANY
540                // signature: BIT STRING
541                0x03, 0x02, 0x00, 0x01 };
542    }
543    //--------------------------------------------------------------------------
544
545    // Second example
546    /**
547     * Certificate:
548     * <pre>
549     * $ openssl req -x509 -nodes -days 365 -subj '/C=AN/ST=Android/O=Android/OU=Android/CN=Android/emailAddress=android' -newkey rsa:1024 -keyout root.pem -out root.pem -text -days 36500
550     * Generating a 1024 bit RSA private key
551     * ..........................................++++++
552     * .................++++++
553     * writing new private key to 'root.pem'
554     * -----BEGIN RSA PRIVATE KEY-----
555     * MIICXwIBAAKBgQDKS+qP2kgqYBtwY4QoJ5p0yyEl35sBr2ZKtAWn6SL4vXgvaIrj
556     * K7vG93CvG239bXfacniGMEBitedBlcqjdPREEY0DQn3jLXyAOd3tnlKcutNH3RjA
557     * fPlnDWNGKLnDdSd9QZEc0G1MsMg/HrERPm1hMfZQG85zdtbYmi2CJ/jS5wIDAQAB
558     * AoGBAIZhvdSHjS7RHwkeonjGLh1tnnx5OI/7AzmWsrci8L9JpZ/gk3pq39dBIhLA
559     * ZuVVpatwJU4GmY65BYEUz0Kb+3JY0PXagypwQKuWs9wb9C0aRnDVy9DNXkbJ+D+L
560     * DNvyZAG5BNknZapxsFSenR5UO4BY08wIsdBtWD/B7YcMTuvxAkEA9zKP18pJCmku
561     * TUDTJkonF/fGvI4PvsBm6YFyINb130yGzKJKCcEn5j2Fm+wF+lGY7nmtUIgQekRm
562     * WkwbjG/v3wJBANGACjKFVIFvuXH6EoyWx90uYw9C8+m2jOtrRaAMfRyUanCvF2Li
563     * ZYOLThPcxv/QvvQAa7RKJjxsK69Ajm+b3fkCQQCR7xWgTVmlfcbJ8LU265v8uFhp
564     * RGzjLe8Td0oLPRxWQXVrJXwUGiYV9MgF7ubwim+AifDZlBo2NF9Ae6Hf3M19AkEA
565     * nJEGDe+a0gj/HHD5f9wHjgLmwTcWNmnZMu8+X3g14DACxCf2YE4183MebLWoevI0
566     * YwIVe+2WWb21gAnM6RghcQJBALq0RZcYkZoQA8qr9TPuuMzi+fF3Y+4m/pDDcCd5
567     * zXbsroEZPdWPfAXKT95juW9yKdVzeOZHO1uwRWmQ9ZlPMhY=
568     * -----END RSA PRIVATE KEY-----
569     * -----
570     * Certificate:
571     *     Data:
572     *         Version: 3 (0x2)
573     *         Serial Number:
574     *             8a:12:37:ed:2d:ad:02:6e
575     *         Signature Algorithm: sha1WithRSAEncryption
576     *         Issuer: C=AN, ST=Android, O=Android, OU=Android, CN=Android/emailAddress=android
577     *         Validity
578     *             Not Before: Oct  4 02:20:28 2010 GMT
579     *             Not After : Sep 10 02:20:28 2110 GMT
580     *         Subject: C=AN, ST=Android, O=Android, OU=Android, CN=Android/emailAddress=android
581     *         Subject Public Key Info:
582     *             Public Key Algorithm: rsaEncryption
583     *             RSA Public Key: (1024 bit)
584     *                 Modulus (1024 bit):
585     *                     00:ca:4b:ea:8f:da:48:2a:60:1b:70:63:84:28:27:
586     *                     9a:74:cb:21:25:df:9b:01:af:66:4a:b4:05:a7:e9:
587     *                     22:f8:bd:78:2f:68:8a:e3:2b:bb:c6:f7:70:af:1b:
588     *                     6d:fd:6d:77:da:72:78:86:30:40:62:b5:e7:41:95:
589     *                     ca:a3:74:f4:44:11:8d:03:42:7d:e3:2d:7c:80:39:
590     *                     dd:ed:9e:52:9c:ba:d3:47:dd:18:c0:7c:f9:67:0d:
591     *                     63:46:28:b9:c3:75:27:7d:41:91:1c:d0:6d:4c:b0:
592     *                     c8:3f:1e:b1:11:3e:6d:61:31:f6:50:1b:ce:73:76:
593     *                     d6:d8:9a:2d:82:27:f8:d2:e7
594     *                 Exponent: 65537 (0x10001)
595     *         X509v3 extensions:
596     *             X509v3 Subject Key Identifier:
597     *                 14:7D:36:ED:63:44:BF:4F:DB:7D:28:96:78:6A:E7:EC:CE:2C:40:BF
598     *             X509v3 Authority Key Identifier:
599     *                 keyid:14:7D:36:ED:63:44:BF:4F:DB:7D:28:96:78:6A:E7:EC:CE:2C:40:BF
600     *                 DirName:/C=AN/ST=Android/O=Android/OU=Android/CN=Android/emailAddress=android
601     *                 serial:8A:12:37:ED:2D:AD:02:6E
602     *
603     *             X509v3 Basic Constraints:
604     *                 CA:TRUE
605     *     Signature Algorithm: sha1WithRSAEncryption
606     *         7c:f2:84:c0:ee:40:a5:b9:94:85:19:ab:36:02:1d:17:4b:98:
607     *         f9:b9:c8:c5:1a:b0:c1:4f:0f:1d:1c:e8:c4:cf:c7:87:52:19:
608     *         9e:64:55:35:bb:34:e1:38:2f:27:08:c5:ca:e7:97:02:90:fd:
609     *         27:cd:8e:5a:08:40:f5:34:ff:70:65:c4:d6:1f:70:4f:d6:2c:
610     *         cb:28:d8:ed:91:b7:eb:35:06:cd:0e:02:a8:51:cd:b7:3e:f9:
611     *         85:16:97:31:7b:42:4c:cb:6f:de:4b:dd:ae:5e:9d:ef:84:83:
612     *         89:f9:0f:a6:5f:e4:93:cc:30:b5:e9:1d:f4:08:f4:e6:e9:58:
613     *         4b:ba
614     * -----BEGIN CERTIFICATE-----
615     * MIIDLTCCApagAwIBAgIJAIoSN+0trQJuMA0GCSqGSIb3DQEBBQUAMG0xCzAJBgNV
616     * BAYTAkFOMRAwDgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQKEwdBbmRyb2lkMRAwDgYD
617     * VQQLEwdBbmRyb2lkMRAwDgYDVQQDEwdBbmRyb2lkMRYwFAYJKoZIhvcNAQkBFgdh
618     * bmRyb2lkMCAXDTEwMTAwNDAyMjAyOFoYDzIxMTAwOTEwMDIyMDI4WjBtMQswCQYD
619     * VQQGEwJBTjEQMA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEChMHQW5kcm9pZDEQMA4G
620     * A1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEWMBQGCSqGSIb3DQEJARYH
621     * YW5kcm9pZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAykvqj9pIKmAbcGOE
622     * KCeadMshJd+bAa9mSrQFp+ki+L14L2iK4yu7xvdwrxtt/W132nJ4hjBAYrXnQZXK
623     * o3T0RBGNA0J94y18gDnd7Z5SnLrTR90YwHz5Zw1jRii5w3UnfUGRHNBtTLDIPx6x
624     * ET5tYTH2UBvOc3bW2Jotgif40ucCAwEAAaOB0jCBzzAdBgNVHQ4EFgQUFH027WNE
625     * v0/bfSiWeGrn7M4sQL8wgZ8GA1UdIwSBlzCBlIAUFH027WNEv0/bfSiWeGrn7M4s
626     * QL+hcaRvMG0xCzAJBgNVBAYTAkFOMRAwDgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQK
627     * EwdBbmRyb2lkMRAwDgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQDEwdBbmRyb2lkMRYw
628     * FAYJKoZIhvcNAQkBFgdhbmRyb2lkggkAihI37S2tAm4wDAYDVR0TBAUwAwEB/zAN
629     * BgkqhkiG9w0BAQUFAAOBgQB88oTA7kCluZSFGas2Ah0XS5j5ucjFGrDBTw8dHOjE
630     * z8eHUhmeZFU1uzThOC8nCMXK55cCkP0nzY5aCED1NP9wZcTWH3BP1izLKNjtkbfr
631     * NQbNDgKoUc23PvmFFpcxe0JMy2/eS92uXp3vhIOJ+Q+mX+STzDC16R30CPTm6VhL
632     * ug==
633     * -----END CERTIFICATE-----
634     * $
635     * </pre>
636     */
637    public static final String rootCert = ""
638            + "-----BEGIN CERTIFICATE-----\n"
639            + "MIIDLTCCApagAwIBAgIJAIoSN+0trQJuMA0GCSqGSIb3DQEBBQUAMG0xCzAJBgNV\n"
640            + "BAYTAkFOMRAwDgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQKEwdBbmRyb2lkMRAwDgYD\n"
641            + "VQQLEwdBbmRyb2lkMRAwDgYDVQQDEwdBbmRyb2lkMRYwFAYJKoZIhvcNAQkBFgdh\n"
642            + "bmRyb2lkMCAXDTEwMTAwNDAyMjAyOFoYDzIxMTAwOTEwMDIyMDI4WjBtMQswCQYD\n"
643            + "VQQGEwJBTjEQMA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEChMHQW5kcm9pZDEQMA4G\n"
644            + "A1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEWMBQGCSqGSIb3DQEJARYH\n"
645            + "YW5kcm9pZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAykvqj9pIKmAbcGOE\n"
646            + "KCeadMshJd+bAa9mSrQFp+ki+L14L2iK4yu7xvdwrxtt/W132nJ4hjBAYrXnQZXK\n"
647            + "o3T0RBGNA0J94y18gDnd7Z5SnLrTR90YwHz5Zw1jRii5w3UnfUGRHNBtTLDIPx6x\n"
648            + "ET5tYTH2UBvOc3bW2Jotgif40ucCAwEAAaOB0jCBzzAdBgNVHQ4EFgQUFH027WNE\n"
649            + "v0/bfSiWeGrn7M4sQL8wgZ8GA1UdIwSBlzCBlIAUFH027WNEv0/bfSiWeGrn7M4s\n"
650            + "QL+hcaRvMG0xCzAJBgNVBAYTAkFOMRAwDgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQK\n"
651            + "EwdBbmRyb2lkMRAwDgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQDEwdBbmRyb2lkMRYw\n"
652            + "FAYJKoZIhvcNAQkBFgdhbmRyb2lkggkAihI37S2tAm4wDAYDVR0TBAUwAwEB/zAN\n"
653            + "BgkqhkiG9w0BAQUFAAOBgQB88oTA7kCluZSFGas2Ah0XS5j5ucjFGrDBTw8dHOjE\n"
654            + "z8eHUhmeZFU1uzThOC8nCMXK55cCkP0nzY5aCED1NP9wZcTWH3BP1izLKNjtkbfr\n"
655            + "NQbNDgKoUc23PvmFFpcxe0JMy2/eS92uXp3vhIOJ+Q+mX+STzDC16R30CPTm6VhL\n"
656            + "ug==\n"
657            + "-----END CERTIFICATE-----\n";
658
659    /**
660     * Certificate:
661     * <pre>
662     * $ openssl req -nodes -days 365 -subj '/C=AN/ST=Android/L=Android/O=Android/OU=Android/CN=Android Certificate/emailAddress=android' -newkey rsa:1024 -keyout certreq.pem -out certreq.pem -text -days 36500
663     * Generating a 1024 bit RSA private key
664     * .......++++++
665     * ......................++++++
666     * writing new private key to 'certreq.pem'
667     * -----
668     * $ openssl x509 -req -in certreq.pem -CA root.pem -CAcreateserial -out cert.pem -days 36500
669     * Signature ok
670     * subject=/C=AN/ST=Android/L=Android/O=Android/OU=Android/CN=Android Certificate/emailAddress=android
671     * Getting Private key
672     * $ rm root.srl
673     * $ openssl rsa -in certreq.pem
674     * writing RSA key
675     * -----BEGIN RSA PRIVATE KEY-----
676     * MIICXQIBAAKBgQDGvQZRB7fsuLvnZ0Sx43sTCkvwv/SEYrzRumyV16OC+lvKGC2X
677     * lYW9qv7of88hqSVq5823MB+uEP1xZLWaiKkYyEn72RwgV/HqB8KEgGYXEbMKKzUv
678     * j0D1X8kZ/EDGqsZjFKlk/7sZYcg3UqCcGUiEEszTadhyJ6FcowHM1EhrcQIDAQAB
679     * AoGAS4CQn8Qw6ewc5wLipDpqDYfB5grnGExys7MBgcPUyPPYX2TkHUye7LnD8gxs
680     * YrtiDcVW8BuGTZkC0EuUesskgiwGLimNiU3vU3LwH7OvtfUTMdvhv9nd2GFlfiQo
681     * PfwhITZ85GwhDkhiBBXjToDcNc0ntXVgACNAKU1ZlJyoyukCQQDwsGmD0GwKFtJH
682     * cGXI+IK0aB+pXjujZJU/Ikg+eTPMSWDsKD6ReZu9uJJc8W36Xiki/No1/NZvj0gB
683     * MwgIkwh7AkEA02FzaGcWLFSHaRfV1wpx1F3Iuu3X2wWqTzBlhGG9ZDQyy7gWZqHJ
684     * jElCdajiMnbh0mk62hobYy4FcLuvkkJWAwJBAK7FKpkQaqMY1zAQqZg4+4/MW9E8
685     * H8oRa14gopzanYYlcj+JKYWw7CnjMERU+yrl3LEPMdQp9/uh6wMT7y1qtqkCQCNG
686     * mxTsRzYEsUhnkuc9Nfvj3tDbSm+hxWdLw1VRXmLvlx6KTSq5i0IfI7kxAva7Ajq0
687     * Fv845iMqFfxXRhiZe3MCQQCxD0vLzEBegLQPgiavGXfBnRPrRrXgkuAJg7Fq/1Vt
688     * 3InSGat3Tv8GW+pCWWVgmV8iQ4wWReg+Bd03SCSP5uAY
689     * -----END RSA PRIVATE KEY-----
690     * $ openssl x509 -in cert.pem -text
691     * Certificate:
692     *     Data:
693     *         Version: 1 (0x0)
694     *         Serial Number:
695     *             89:34:5f:d5:01:2e:a2:2b
696     *         Signature Algorithm: sha1WithRSAEncryption
697     *         Issuer: C=AN, ST=Android, O=Android, OU=Android, CN=Android/emailAddress=android
698     *         Validity
699     *             Not Before: Oct  4 04:41:54 2010 GMT
700     *             Not After : Sep 10 04:41:54 2110 GMT
701     *         Subject: C=AN, ST=Android, L=Android, O=Android, OU=Android, CN=Android Certificate/emailAddress=android
702     *         Subject Public Key Info:
703     *             Public Key Algorithm: rsaEncryption
704     *             RSA Public Key: (1024 bit)
705     *                 Modulus (1024 bit):
706     *                     00:c6:bd:06:51:07:b7:ec:b8:bb:e7:67:44:b1:e3:
707     *                     7b:13:0a:4b:f0:bf:f4:84:62:bc:d1:ba:6c:95:d7:
708     *                     a3:82:fa:5b:ca:18:2d:97:95:85:bd:aa:fe:e8:7f:
709     *                     cf:21:a9:25:6a:e7:cd:b7:30:1f:ae:10:fd:71:64:
710     *                     b5:9a:88:a9:18:c8:49:fb:d9:1c:20:57:f1:ea:07:
711     *                     c2:84:80:66:17:11:b3:0a:2b:35:2f:8f:40:f5:5f:
712     *                     c9:19:fc:40:c6:aa:c6:63:14:a9:64:ff:bb:19:61:
713     *                     c8:37:52:a0:9c:19:48:84:12:cc:d3:69:d8:72:27:
714     *                     a1:5c:a3:01:cc:d4:48:6b:71
715     *                 Exponent: 65537 (0x10001)
716     *     Signature Algorithm: sha1WithRSAEncryption
717     *         80:06:54:ba:4c:a2:0d:2e:6b:d5:b0:b1:89:b2:fa:c2:fd:d6:
718     *         02:ab:74:af:fb:1c:bc:47:43:58:89:57:80:ad:59:79:e9:2e:
719     *         d9:60:a7:a6:0f:9c:10:9f:e1:80:a1:66:19:59:7e:11:28:17:
720     *         17:0a:1d:e9:8d:78:e8:c2:61:36:03:fc:42:b1:54:bd:28:39:
721     *         3c:48:fd:3c:79:e7:ca:1a:16:c3:8a:77:42:07:96:14:8c:d2:
722     *         51:ca:8e:db:b8:82:31:84:5e:3f:68:b1:a5:f0:96:ae:a9:ca:
723     *         86:f3:01:76:63:98:65:dd:41:81:11:d7:71:c8:ae:17:c7:20:
724     *         e7:22
725     * -----BEGIN CERTIFICATE-----
726     * MIICcjCCAdsCCQCJNF/VAS6iKzANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJB
727     * TjEQMA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMH
728     * QW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEWMBQGCSqGSIb3DQEJARYHYW5kcm9p
729     * ZDAgFw0xMDEwMDQwNDQxNTRaGA8yMTEwMDkxMDA0NDE1NFowgYsxCzAJBgNVBAYT
730     * AkFOMRAwDgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQHEwdBbmRyb2lkMRAwDgYDVQQK
731     * EwdBbmRyb2lkMRAwDgYDVQQLEwdBbmRyb2lkMRwwGgYDVQQDExNBbmRyb2lkIENl
732     * cnRpZmljYXRlMRYwFAYJKoZIhvcNAQkBFgdhbmRyb2lkMIGfMA0GCSqGSIb3DQEB
733     * AQUAA4GNADCBiQKBgQDGvQZRB7fsuLvnZ0Sx43sTCkvwv/SEYrzRumyV16OC+lvK
734     * GC2XlYW9qv7of88hqSVq5823MB+uEP1xZLWaiKkYyEn72RwgV/HqB8KEgGYXEbMK
735     * KzUvj0D1X8kZ/EDGqsZjFKlk/7sZYcg3UqCcGUiEEszTadhyJ6FcowHM1EhrcQID
736     * AQABMA0GCSqGSIb3DQEBBQUAA4GBAIAGVLpMog0ua9WwsYmy+sL91gKrdK/7HLxH
737     * Q1iJV4CtWXnpLtlgp6YPnBCf4YChZhlZfhEoFxcKHemNeOjCYTYD/EKxVL0oOTxI
738     * /Tx558oaFsOKd0IHlhSM0lHKjtu4gjGEXj9osaXwlq6pyobzAXZjmGXdQYER13HI
739     * rhfHIOci
740     * -----END CERTIFICATE-----
741     * $
742     * </pre>
743     */
744    public static final String  endCert = ""
745            + "-----BEGIN CERTIFICATE-----\n"
746            + "MIICcjCCAdsCCQCJNF/VAS6iKzANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJB\n"
747            + "TjEQMA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMH\n"
748            + "QW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEWMBQGCSqGSIb3DQEJARYHYW5kcm9p\n"
749            + "ZDAgFw0xMDEwMDQwNDQxNTRaGA8yMTEwMDkxMDA0NDE1NFowgYsxCzAJBgNVBAYT\n"
750            + "AkFOMRAwDgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQHEwdBbmRyb2lkMRAwDgYDVQQK\n"
751            + "EwdBbmRyb2lkMRAwDgYDVQQLEwdBbmRyb2lkMRwwGgYDVQQDExNBbmRyb2lkIENl\n"
752            + "cnRpZmljYXRlMRYwFAYJKoZIhvcNAQkBFgdhbmRyb2lkMIGfMA0GCSqGSIb3DQEB\n"
753            + "AQUAA4GNADCBiQKBgQDGvQZRB7fsuLvnZ0Sx43sTCkvwv/SEYrzRumyV16OC+lvK\n"
754            + "GC2XlYW9qv7of88hqSVq5823MB+uEP1xZLWaiKkYyEn72RwgV/HqB8KEgGYXEbMK\n"
755            + "KzUvj0D1X8kZ/EDGqsZjFKlk/7sZYcg3UqCcGUiEEszTadhyJ6FcowHM1EhrcQID\n"
756            + "AQABMA0GCSqGSIb3DQEBBQUAA4GBAIAGVLpMog0ua9WwsYmy+sL91gKrdK/7HLxH\n"
757            + "Q1iJV4CtWXnpLtlgp6YPnBCf4YChZhlZfhEoFxcKHemNeOjCYTYD/EKxVL0oOTxI\n"
758            + "/Tx558oaFsOKd0IHlhSM0lHKjtu4gjGEXj9osaXwlq6pyobzAXZjmGXdQYER13HI\n"
759            + "rhfHIOci\n"
760            + "-----END CERTIFICATE-----\n";
761
762    /**
763     * a self signed certificate
764     */
765    public static X509Certificate rootCertificateSS;
766
767    public static X509Certificate endCertificate;
768
769    public static MyCRL crl;
770
771    public static X509CertSelector theCertSelector;
772
773    public static CertPathBuilder builder;
774    private static CertStore store;
775
776    public static void initCertPathSSCertChain() throws CertificateException,
777            InvalidAlgorithmParameterException, NoSuchAlgorithmException,
778            IOException {
779        // create certificates and CRLs
780        CertificateFactory cf = CertificateFactory.getInstance("X.509");
781        ByteArrayInputStream bi = new ByteArrayInputStream(rootCert.getBytes());
782        rootCertificateSS = (X509Certificate) cf.generateCertificate(bi);
783        bi = new ByteArrayInputStream(endCert.getBytes());
784        endCertificate = (X509Certificate) cf.generateCertificate(bi);
785        BigInteger revokedSerialNumber = BigInteger.valueOf(1);
786        crl = new MyCRL("X.509");
787//        X509CRL rootCRL = X509CRL;
788//        X509CRL interCRL = X509CRLExample.createCRL(interCert, interPair
789//                .getPrivate(), revokedSerialNumber);
790
791        // create CertStore to support path building
792        List<Object> list = new ArrayList<Object>();
793
794        list.add(rootCertificateSS);
795        list.add(endCertificate);
796
797        CollectionCertStoreParameters params = new CollectionCertStoreParameters(
798                list);
799        store = CertStore.getInstance("Collection", params);
800
801        theCertSelector = new X509CertSelector();
802        theCertSelector.setCertificate(endCertificate);
803        theCertSelector.setIssuer(endCertificate.getIssuerX500Principal()
804                .getEncoded());
805
806        // build the path
807        builder = CertPathBuilder.getInstance("PKIX");
808
809    }
810
811    public static CertPathBuilder getCertPathBuilder() {
812        if (builder == null) {
813            throw new RuntimeException(
814            "Call initCertPathSSCertChain prior to initCertPathSSCertChain");
815        }
816        return builder;
817    }
818
819    public static CertPath buildCertPathSSCertChain() throws Exception {
820        return builder.build(getCertPathParameters()).getCertPath();
821    }
822
823    public static CertPathParameters getCertPathParameters()
824            throws InvalidAlgorithmParameterException {
825        if ((rootCertificateSS == null) || (theCertSelector == null)
826                || (builder == null)) {
827            throw new RuntimeException(
828                    "Call initCertPathSSCertChain prior to buildCertPath");
829        }
830        PKIXBuilderParameters buildParams = new PKIXBuilderParameters(
831                Collections.singleton(new TrustAnchor(rootCertificateSS, null)),
832                theCertSelector);
833
834        buildParams.addCertStore(store);
835        buildParams.setRevocationEnabled(false);
836
837        return buildParams;
838
839    }
840}
841