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
18package tests.security.cert;
19
20import dalvik.annotation.TestLevel;
21import dalvik.annotation.TestTargetClass;
22import dalvik.annotation.TestTargetNew;
23import dalvik.annotation.TestTargets;
24
25import org.apache.harmony.security.tests.support.cert.TestUtils;
26
27import java.io.ByteArrayInputStream;
28import java.math.BigInteger;
29import java.security.Principal;
30import java.security.PublicKey;
31import java.security.cert.CertificateException;
32import java.security.cert.CertificateFactory;
33import java.security.cert.CertificateParsingException;
34import java.security.cert.X509Certificate;
35import java.security.cert.X509Extension;
36import java.util.Arrays;
37import java.util.Collection;
38import java.util.Date;
39import java.util.List;
40import java.util.Set;
41
42import javax.security.auth.x500.X500Principal;
43
44@TestTargetClass(X509Certificate.class)
45public class X509Certificate2Test extends junit.framework.TestCase {
46
47    /**
48     * Test for X.509 Certificate provider
49     */
50    @TestTargetNew(
51        level = TestLevel.COMPLETE,
52        notes = "",
53        method = "toString",
54        args = {}
55    )
56    public void test_toString() throws Exception {
57
58        // Regression for HARMONY-3384
59        CertificateFactory certFact = CertificateFactory.getInstance("X509");
60        X509Certificate pemCert = (X509Certificate) certFact
61                .generateCertificate(new ByteArrayInputStream(TestUtils
62                        .getX509Certificate_v3()));
63
64        // extension value is empty sequence
65        byte[] extnValue = pemCert.getExtensionValue("2.5.29.35");
66        assertTrue(Arrays
67                .equals(new byte[] {0x04, 0x02, 0x30, 0x00}, extnValue));
68        assertNotNull(pemCert.toString());
69        // End regression for HARMONY-3384
70    }
71
72    /**
73     * @tests java.security.cert.X509Certificate#X509Certificate()
74     */
75    @TestTargetNew(
76        level = TestLevel.COMPLETE,
77        notes = "",
78        method = "X509Certificate",
79        args = {}
80    )
81    public void test_X509Certificate() {
82        MyX509Certificate s = null;
83        try {
84            s = new MyX509Certificate();
85        } catch (Exception e) {
86            fail("Unexpected exception " + e.getMessage());
87        }
88        assertEquals("X.509", s.getType());
89    }
90
91    @TestTargets({
92        @TestTargetNew(
93            level = TestLevel.COMPLETE,
94            notes = "",
95            method = "checkValidity",
96            args = {}
97        ),
98        @TestTargetNew(
99            level = TestLevel.COMPLETE,
100            notes = "",
101            method = "checkValidity",
102            args = {java.util.Date.class}
103        ),
104        @TestTargetNew(
105            level = TestLevel.COMPLETE,
106            notes = "",
107            method = "getBasicConstraints",
108            args = {}
109        ),
110        @TestTargetNew(
111            level = TestLevel.COMPLETE,
112            notes = "",
113            method = "getIssuerDN",
114            args = {}
115        ),
116        @TestTargetNew(
117            level = TestLevel.COMPLETE,
118            notes = "",
119            method = "getIssuerUniqueID",
120            args = {}
121        ),
122        @TestTargetNew(
123            level = TestLevel.COMPLETE,
124            notes = "",
125            method = "getKeyUsage",
126            args = {}
127        ),
128        @TestTargetNew(
129            level = TestLevel.COMPLETE,
130            notes = "",
131            method = "getNotAfter",
132            args = {}
133        ),
134        @TestTargetNew(
135            level = TestLevel.COMPLETE,
136            notes = "",
137            method = "getNotBefore",
138            args = {}
139        ),
140        @TestTargetNew(
141            level = TestLevel.COMPLETE,
142            notes = "",
143            method = "getSerialNumber",
144            args = {}
145        ),
146        @TestTargetNew(
147            level = TestLevel.COMPLETE,
148            notes = "",
149            method = "getSigAlgName",
150            args = {}
151        ),
152        @TestTargetNew(
153            level = TestLevel.COMPLETE,
154            notes = "",
155            method = "getSigAlgOID",
156            args = {}
157        ),
158        @TestTargetNew(
159            level = TestLevel.COMPLETE,
160            notes = "",
161            method = "getSigAlgParams",
162            args = {}
163        ),
164        @TestTargetNew(
165            level = TestLevel.COMPLETE,
166            notes = "",
167            method = "getSignature",
168            args = {}
169        ),
170        @TestTargetNew(
171            level = TestLevel.COMPLETE,
172            notes = "",
173            method = "getSubjectDN",
174            args = {}
175        ),
176        @TestTargetNew(
177            level = TestLevel.COMPLETE,
178            notes = "",
179            method = "getSubjectUniqueID",
180            args = {}
181        ),
182        @TestTargetNew(
183            level = TestLevel.COMPLETE,
184            notes = "",
185            method = "getTBSCertificate",
186            args = {}
187        ),
188        @TestTargetNew(
189            level = TestLevel.COMPLETE,
190            notes = "",
191            method = "getVersion",
192            args = {}
193        )
194    })
195    public void testAbstractMethods() {
196        MyX509Certificate s = new MyX509Certificate();
197        try {
198            s.checkValidity();
199            s.checkValidity(new Date());
200            s.getBasicConstraints();
201            s.getIssuerDN();
202            s.getIssuerUniqueID();
203            s.getKeyUsage();
204            s.getNotAfter();
205            s.getNotBefore();
206            s.getSerialNumber();
207            s.getSigAlgName();
208            s.getSigAlgOID();
209            s.getSigAlgParams();
210            s.getSignature();
211            s.getSubjectDN();
212            s.getSubjectUniqueID();
213            s.getTBSCertificate();
214            s.getVersion();
215        } catch (Exception e) {
216            fail("Unexpected exception " + e.getMessage());
217        }
218    }
219
220    // Base64 encoded form of ASN.1 DER encoded X.509 Certificate
221    // (see RFC 3280 at http://www.ietf.org/rfc/rfc3280.txt)
222    // (generated by using of classes from
223    // org.apache.harmony.security.x509 package)
224    static String base64cert =
225        "MIIByzCCATagAwIBAgICAiswCwYJKoZIhvcNAQEFMB0xGzAZBgNVBAoT"
226            + "EkNlcnRpZmljYXRlIElzc3VlcjAeFw0wNjA0MjYwNjI4MjJaFw0zMzAz"
227            + "MDExNjQ0MDlaMB0xGzAZBgNVBAoTEkNlcnRpZmljYXRlIElzc3VlcjCB"
228            + "nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAkLGLsPdSPDMyP1OUOKu"
229            + "U3cvbNK5RGaQ3bXc5aDjvApx43BcaoXgt6YD/5yXz0OsIooj5yA37bY"
230            + "JGcVrvFD5FMPdDd3vjNPQOep0MzG4CdbkaZde5SigPabOMQYS4oUyLBx"
231            + "W3LGG0mUODe5AGGqtqXU0GlKg4K2je6cCtookCUCAwEAAaMeMBwwGgYD"
232            + "VR0RAQH/BBAwDoEMcmZjQDgyMi5OYW1lMAsGCSqGSIb3DQEBBQOBgQBZ"
233            + "pVXj01dOpqnZErUQb50j8lJD1dIaz1eJTvJCSadj7ziV1VtnnapI07c"
234            + "XEa7ONzcHQTYTG10poHfOK/a0BaULF3GlctDESilwQYbW5BdfpAlZpbH"
235            + "AFLcUDh6Eq50kc0A/anh/j3mgBNuvbIMo7hHNnZB6k/prswm2BszyLD"
236            + "yw==";
237    static String base64certCorrect =
238        "-----BEGIN CERTIFICATE-----\n"
239        + "MIIC+jCCAragAwIBAgICAiswDAYHKoZIzjgEAwEBADAdMRswGQYDVQQKExJDZXJ0a"
240        + "WZpY2F0ZSBJc3N1ZXIwIhgPMTk3MDAxMTIxMzQ2NDBaGA8xOTcwMDEyNDAzMzMyMF"
241        + "owHzEdMBsGA1UEChMUU3ViamVjdCBPcmdhbml6YXRpb24wGTAMBgcqhkjOOAQDAQE"
242        + "AAwkAAQIDBAUGBwiBAgCqggIAVaOCAhQwggIQMA8GA1UdDwEB/wQFAwMBqoAwEgYD"
243        + "VR0TAQH/BAgwBgEB/wIBBTAUBgNVHSABAf8ECjAIMAYGBFUdIAAwZwYDVR0RAQH/B"
244        + "F0wW4EMcmZjQDgyMi5OYW1lggdkTlNOYW1lpBcxFTATBgNVBAoTDE9yZ2FuaXphdG"
245        + "lvboYaaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWSHBP///wCIByoDolyDsgMwDAY"
246        + "DVR0eAQH/BAIwADAMBgNVHSQBAf8EAjAAMIGZBgNVHSUBAf8EgY4wgYsGBFUdJQAG"
247        + "CCsGAQUFBwMBBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDB"
248        + "AYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUFBw"
249        + "MJBggrBgEFBQgCAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GA1UdNgEB/wQDAgE"
250        + "BMA4GBCpNhgkBAf8EAwEBATBkBgNVHRIEXTBbgQxyZmNAODIyLk5hbWWCB2ROU05h"
251        + "bWWkFzEVMBMGA1UEChMMT3JnYW5pemF0aW9uhhpodHRwOi8vdW5pZm9ybS5SZXNvd"
252        + "XJjZS5JZIcE////AIgHKgOiXIOyAzAJBgNVHR8EAjAAMAoGA1UdIwQDAQEBMAoGA1"
253        + "UdDgQDAQEBMAoGA1UdIQQDAQEBMAwGByqGSM44BAMBAQADMAAwLQIUAL4QvoazNWP"
254        + "7jrj84/GZlhm09DsCFQCBKGKCGbrP64VtUt4JPmLjW1VxQA==\n"
255        + "-----END CERTIFICATE-----";
256
257    private X509Certificate cert;
258
259    static String base64certTampered = "-----BEGIN CERTIFICATE-----\n"
260        + "MIIC+jCCAragAwIBAgICAiswDAYHKoZIzjgEAwEBADAdMRswGQYDVQQKExJDZXJ0a"
261        + "WZpY2F0ZSBJc3N1ZXIwIhgPMTk3MDAxMTIxMzQ2NDBaGA8xOTcwMDEyNDAzMzMyMF"
262        + "owHzEdMBsGA1UEChMUU3ViamVjdCBPcmdhbml6YXRpb24wGTAMBgcqhkjOOAQDAQE"
263        + "AAwkAAQIDBAUGBwiBAgCqggIAVaOCAhQwggIQMA8GA1UdDwEB/wQFAwMBqoAwEgYD"
264        + "VR0TAQH/BAgwBgEB/wIBBTAUBgNVHSABAf8ECjAIMAyGBFUdIAAwZwYDVR0RAQH/B"
265        + "F0wW4EMcmZjQDgyMi5OYW1lggdkTlNOYW1lpBcxFTATBgNVBAoTDE9yZ2FuaXphdG"
266        + "lvboYaaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWSHBP///wCIByoDolyDsgMwDAY"
267        + "DVR0eAQH/BAIwADAMBgNVHSQBAf8EAjAAMIGZBgNVHSUBAf8EgY4wgYsGBFUdJQAG"
268        + "CCsGAQUFBwMBBggrBgEFBQcDAQYIKxYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDB"
269        + "AYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUFBw"
270        + "MJBggrBgEFBQgCAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GA1UdNgEB/wQDAgE"
271        + "BMA4GBCpNhgkBAf8EAwEBATBkBgNVHRIEXTBbgQxyZmNAODIyLk5hbWWCB2ROU05h"
272        + "bWWkFzEVMBMGA1UEChMMT3JnYW5pemF0aW9uhhpodHRwOi8vdW5pZm9ybS5SZXNvd"
273        + "XJjZS5JZIcE////AIgHKgOiXIOyAzAJBgNVHR8EAjAAMAoGA1UdIwQDAQEBMAoGA1"
274        + "UdDgQDAQEBMAoGA1UdIQQDAQEBMAwHByqGSM44BAMBAQADMAAwLQIUAL4QvoazNWP"
275        + "7jrj84/GZlhm09DsCFQCBKGKCGbrP64VtUt4JPmLjW1VxQA==\n"
276        + "-----END CERTIFICATE-----";
277
278    // Base64 encoded form of ASN.1 DER encoded X.509 CRL
279    // (see RFC 3280 at http://www.ietf.org/rfc/rfc3280.txt)
280    // (generated by using of classes from
281    // org.apache.harmony.security.x509 package)
282    static String base64crl =
283        "MIHXMIGXAgEBMAkGByqGSM44BAMwFTETMBEGA1UEChMKQ1JMIElzc3Vl"
284            + "chcNMDYwNDI3MDYxMzQ1WhcNMDYwNDI3MDYxNTI1WjBBMD8CAgIrFw0w"
285            + "NjA0MjcwNjEzNDZaMCowCgYDVR0VBAMKAQEwHAYDVR0YBBUYEzIwMDYw"
286            + "NDI3MDYxMzQ1LjQ2OFqgDzANMAsGA1UdFAQEBAQEBDAJBgcqhkjOOAQD"
287            + "AzAAMC0CFQCk0t0DTyu82QpajbBlxX9uXvUDSgIUSBN4g+xTEeexs/0k"
288            + "9AkjBhjF0Es=";
289
290    // has stub implementation for abstract methods
291    private static class MyX509Certificate extends X509Certificate implements
292            X509Extension {
293
294        private static final long serialVersionUID = -7196694072296607007L;
295
296        public void checkValidity() {
297        }
298
299        public void checkValidity(Date date) {
300        }
301
302        public int getVersion() {
303            return 3;
304        }
305
306        public BigInteger getSerialNumber() {
307            return null;
308        }
309
310        public Principal getIssuerDN() {
311            return null;
312        }
313
314        public Principal getSubjectDN() {
315            return null;
316        }
317
318        public Date getNotBefore() {
319            return null;
320        }
321
322        public Date getNotAfter() {
323            return null;
324        }
325
326        public byte[] getTBSCertificate() {
327            return null;
328        }
329
330        public byte[] getSignature() {
331            return null;
332        }
333
334        public String getSigAlgName() {
335            return null;
336        }
337
338        public String getSigAlgOID() {
339            return null;
340        }
341
342        public byte[] getSigAlgParams() {
343            return null;
344        }
345
346        public boolean[] getIssuerUniqueID() {
347            return null;
348        }
349
350        public boolean[] getSubjectUniqueID() {
351            return null;
352        }
353
354        public boolean[] getKeyUsage() {
355            return null;
356        }
357
358        public int getBasicConstraints() {
359            return 0;
360        }
361
362        public void verify(PublicKey key) {
363        }
364
365        public void verify(PublicKey key, String sigProvider) {
366        }
367
368        public String toString() {
369            return "";
370        }
371
372        public PublicKey getPublicKey() {
373            return null;
374        }
375
376        public byte[] getEncoded() {
377            return null;
378        }
379
380        public Set<String> getNonCriticalExtensionOIDs() {
381            return null;
382        }
383
384        public Set<String> getCriticalExtensionOIDs() {
385            return null;
386        }
387
388        public byte[] getExtensionValue(String oid) {
389            return null;
390        }
391
392        public boolean hasUnsupportedCriticalExtension() {
393            return false;
394        }
395    }
396
397    /**
398     * @tests java.security.cert.X509Certificate#getType()
399     */
400    @TestTargetNew(
401        level = TestLevel.COMPLETE,
402        notes = "",
403        method = "getType",
404        args = {}
405    )
406    public void testGetType() {
407        assertEquals("X.509", new MyX509Certificate().getType());
408    }
409
410    /**
411     * @tests java.security.cert.X509Certificate#getIssuerX500Principal()
412     */
413    @TestTargetNew(
414        level = TestLevel.COMPLETE,
415        notes = "",
416        method = "getIssuerX500Principal",
417        args = {}
418    )
419    public void testGetIssuerX500Principal() {
420        // return valid encoding
421        MyX509Certificate cert = new MyX509Certificate() {
422            private static final long serialVersionUID = 638659908323741165L;
423
424            public byte[] getEncoded() {
425                return TestUtils.getX509Certificate_v1();
426            }
427        };
428
429        assertEquals(new X500Principal("CN=Z"), cert.getIssuerX500Principal());
430    }
431
432    /**
433     * @tests java.security.cert.X509Certificate#getSubjectX500Principal()
434     */
435    @TestTargetNew(
436        level = TestLevel.COMPLETE,
437        notes = "",
438        method = "getSubjectX500Principal",
439        args = {}
440    )
441    public void testGetSubjectX500Principal() {
442        // return valid encoding
443        MyX509Certificate cert = new MyX509Certificate() {
444            private static final long serialVersionUID = -3625913637413840694L;
445
446            public byte[] getEncoded() {
447                return TestUtils.getX509Certificate_v1();
448            }
449        };
450
451        assertEquals(new X500Principal("CN=Y"), cert.getSubjectX500Principal());
452    }
453
454    /**
455     * @throws CertificateException
456     * @tests java.security.cert.X509Certificate#getExtendedKeyUsage()
457     */
458    @TestTargetNew(
459        level = TestLevel.SUFFICIENT,
460        notes = "Doesn't verify CertificateParsingException.",
461        method = "getExtendedKeyUsage",
462        args = {}
463    )
464    public void testGetExtendedKeyUsage() throws CertificateException {
465        assertNull(new MyX509Certificate().getExtendedKeyUsage());
466
467        List<String> l = cert.getExtendedKeyUsage();
468        assertNotNull(l);
469
470        try {
471            l.clear();
472        } catch (Exception e) {
473            // ok
474        }
475
476        try {
477            l.add("Test");
478        } catch (Exception e) {
479            // ok
480        }
481
482        try {
483            if (l.size() > 0) {
484                l.remove(0);
485            }
486        } catch (Exception e) {
487            // ok
488        }
489
490    }
491
492    /**
493     * @tests java.security.cert.X509Certificate#getSubjectAlternativeNames()
494     */
495    @TestTargetNew(
496        level = TestLevel.SUFFICIENT,
497        notes = "",
498        method = "getSubjectAlternativeNames",
499        args = {}
500    )
501    public void testGetSubjectAlternativeNames()
502            throws CertificateParsingException {
503
504        assertNull(new MyX509Certificate().getSubjectAlternativeNames());
505
506        Collection<List<?>> coll = cert.getSubjectAlternativeNames();
507        //getSubjectAlternativeNames method is not supported
508        assertNotNull(coll);
509
510        try {
511            coll.clear();
512        } catch (Exception e) {
513            // ok
514        }
515
516        try {
517            if (coll.size() > 0) {
518                coll.remove(0);
519            }
520        } catch (Exception e) {
521            // ok
522        }
523
524        assertTrue(coll.size() < 10);
525
526    }
527
528    /**
529     * @tests java.security.cert.X509Certificate#getIssuerAlternativeNames()
530     */
531    @TestTargetNew(
532        level = TestLevel.SUFFICIENT,
533        notes = "Doesn't verify CertificateParsingException.",
534        method = "getIssuerAlternativeNames",
535        args = {}
536    )
537    public void testGetIssuerAlternativeNames()
538            throws CertificateParsingException {
539
540        assertNull(new MyX509Certificate().getIssuerAlternativeNames());
541
542        Collection<List<?>> coll = cert.getIssuerAlternativeNames();
543        // getIssuerAlternativeNames returns null.
544        assertNotNull(coll);
545
546        try {
547            coll.clear();
548        } catch (Exception e) {
549            // ok
550        }
551
552        try {
553            if (coll.size() > 0) {
554                coll.remove(0);
555            }
556        } catch (Exception e) {
557            // ok
558        }
559
560        assertTrue(coll.size() < 10);
561    }
562
563    @TestTargetNew(
564            level = TestLevel.PARTIAL_COMPLETE,
565            notes = "",
566            clazz = CertificateException.class,
567            method = "CertificateException",
568            args = {}
569        )
570    public void testCerficateException() {
571        try {
572            CertificateFactory cf = CertificateFactory.getInstance("X.509");
573            ByteArrayInputStream bais = new ByteArrayInputStream(
574                    base64certTampered.getBytes());
575            cert = (X509Certificate) cf.generateCertificate(bais);
576        } catch (CertificateException e) {
577            // ok
578        }
579
580        try {
581            CertificateFactory cf = CertificateFactory.getInstance("X.509");
582            ByteArrayInputStream bais = new ByteArrayInputStream(base64cert
583                    .getBytes());
584            cert = (X509Certificate) cf.generateCertificate(bais);
585        } catch (CertificateException e) {
586            // ok
587        }
588    }
589
590    public void setUp() throws Exception {
591        super.setUp();
592        CertificateFactory cf = CertificateFactory.getInstance("X.509");
593        ByteArrayInputStream bais = new ByteArrayInputStream(base64certCorrect
594                .getBytes());
595        cert = (X509Certificate) cf.generateCertificate(bais);
596        assertNotNull(cert);
597    }
598}
599