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 Alexander Y. Kleymenov
20 * @version $Revision$
21 */
22
23package tests.api.javax.security.cert;
24
25import dalvik.annotation.BrokenTest;
26import dalvik.annotation.TestLevel;
27import dalvik.annotation.TestTargetClass;
28import dalvik.annotation.TestTargetNew;
29import dalvik.annotation.SideEffect;
30
31import junit.framework.Test;
32import junit.framework.TestCase;
33import junit.framework.TestSuite;
34
35import tests.targets.security.cert.CertificateFactoryTestX509;
36
37import java.io.ByteArrayInputStream;
38import java.io.IOException;
39import java.io.InputStream;
40import java.math.BigInteger;
41import java.security.InvalidKeyException;
42import java.security.NoSuchAlgorithmException;
43import java.security.NoSuchProviderException;
44import java.security.Principal;
45import java.security.Provider;
46import java.security.PublicKey;
47import java.security.Security;
48import java.security.SignatureException;
49import java.security.Provider.Service;
50import java.security.cert.CertificateFactory;
51import java.util.Arrays;
52import java.util.Calendar;
53import java.util.Date;
54import java.util.GregorianCalendar;
55import java.util.Set;
56import java.util.logging.Logger;
57
58import javax.security.cert.Certificate;
59import javax.security.cert.CertificateEncodingException;
60import javax.security.cert.CertificateException;
61import javax.security.cert.CertificateExpiredException;
62import javax.security.cert.CertificateNotYetValidException;
63import javax.security.cert.X509Certificate;
64
65import junit.framework.Test;
66import junit.framework.TestCase;
67import junit.framework.TestSuite;
68import tests.targets.security.cert.CertificateFactoryTestX509;
69import dalvik.annotation.BrokenTest;
70import dalvik.annotation.TestLevel;
71import dalvik.annotation.TestTargetClass;
72import dalvik.annotation.TestTargetNew;
73
74/**
75 */
76@TestTargetClass(X509Certificate.class)
77public class X509CertificateTest extends TestCase {
78
79    // Testing data was generated by using of classes
80    // from org.apache.harmony.security.asn1 package encoded
81    // by org.apache.harmony.misc.Base64 class.
82
83    private static String base64cert = "-----BEGIN CERTIFICATE-----\n"
84            + "MIIC+jCCAragAwIBAgICAiswDAYHKoZIzjgEAwEBADAdMRswGQYDVQQKExJDZXJ0a"
85            + "WZpY2F0ZSBJc3N1ZXIwIhgPMTk3MDAxMTIxMzQ2NDBaGA8xOTcwMDEyNDAzMzMyMF"
86            + "owHzEdMBsGA1UEChMUU3ViamVjdCBPcmdhbml6YXRpb24wGTAMBgcqhkjOOAQDAQE"
87            + "AAwkAAQIDBAUGBwiBAgCqggIAVaOCAhQwggIQMA8GA1UdDwEB/wQFAwMBqoAwEgYD"
88            + "VR0TAQH/BAgwBgEB/wIBBTAUBgNVHSABAf8ECjAIMAYGBFUdIAAwZwYDVR0RAQH/B"
89            + "F0wW4EMcmZjQDgyMi5OYW1lggdkTlNOYW1lpBcxFTATBgNVBAoTDE9yZ2FuaXphdG"
90            + "lvboYaaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWSHBP///wCIByoDolyDsgMwDAY"
91            + "DVR0eAQH/BAIwADAMBgNVHSQBAf8EAjAAMIGZBgNVHSUBAf8EgY4wgYsGBFUdJQAG"
92            + "CCsGAQUFBwMBBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDB"
93            + "AYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUFBw"
94            + "MJBggrBgEFBQgCAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GA1UdNgEB/wQDAgE"
95            + "BMA4GBCpNhgkBAf8EAwEBATBkBgNVHRIEXTBbgQxyZmNAODIyLk5hbWWCB2ROU05h"
96            + "bWWkFzEVMBMGA1UEChMMT3JnYW5pemF0aW9uhhpodHRwOi8vdW5pZm9ybS5SZXNvd"
97            + "XJjZS5JZIcE////AIgHKgOiXIOyAzAJBgNVHR8EAjAAMAoGA1UdIwQDAQEBMAoGA1"
98            + "UdDgQDAQEBMAoGA1UdIQQDAQEBMAwGByqGSM44BAMBAQADMAAwLQIUAL4QvoazNWP"
99            + "7jrj84/GZlhm09DsCFQCBKGKCGbrP64VtUt4JPmLjW1VxQA==\n"
100            + "-----END CERTIFICATE-----";
101
102   /*
103    * a self-signed certificate
104    */
105   private static final String selfSignedCert = "-----BEGIN CERTIFICATE-----\n" +
106   "MIIDPzCCAqigAwIBAgIBADANBgkqhkiG9w0BAQUFADB5MQswCQYDVQQGEwJBTjEQ" +
107   "MA4GA1UECBMHQW5kcm9pZDEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5k" +
108   "cm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBh" +
109   "bmRyb2lkLmNvbTAeFw0wOTAzMjAxNzAwMDZaFw0xMjAzMTkxNzAwMDZaMHkxCzAJ" +
110   "BgNVBAYTAkFOMRAwDgYDVQQIEwdBbmRyb2lkMRAwDgYDVQQKEwdBbmRyb2lkMRAw" +
111   "DgYDVQQLEwdBbmRyb2lkMRAwDgYDVQQDEwdBbmRyb2lkMSIwIAYJKoZIhvcNAQkB" +
112   "FhNhbmRyb2lkQGFuZHJvaWQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB" +
113   "gQCqQkDtkiEXmV8O5EK4y2Y9YyoWNDx70z4fqD+9muuzJGuM5NovMbxhBycuKHF3" +
114   "WK60iXzrsAYkB1c8VHHbcUEFqz2fBdLKyxy/nYohlo8TYSVpEjt3vfc0sgmp4FKU" +
115   "RDHO2z3rZPHWysV9L9ZvjeQpiwaYipU9epdBmvFmxQmCDQIDAQABo4HWMIHTMB0G" +
116   "A1UdDgQWBBTnm32QKeqQC38IQXZOQSPoQyypAzCBowYDVR0jBIGbMIGYgBTnm32Q" +
117   "KeqQC38IQXZOQSPoQyypA6F9pHsweTELMAkGA1UEBhMCQU4xEDAOBgNVBAgTB0Fu" +
118   "ZHJvaWQxEDAOBgNVBAoTB0FuZHJvaWQxEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNV" +
119   "BAMTB0FuZHJvaWQxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5kcm9pZC5jb22C" +
120   "AQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQAUmDApQu+r5rglS1WF" +
121   "BKXE3R2LasFvbBwdw2E0MAc0TWqLVW91VW4VWMX4r+C+c7rZpYXXtRqFRCuI/czL" +
122   "0e1GaUP/Wa6bXBcm2u7Iv2dVAaAOELmFSVTZeR57Lm9lT9kQLp24kmNndIsiDW3T" +
123   "XZ4pY/k2kxungOKx8b8pGYE9Bw==\n" +
124   "-----END CERTIFICATE-----";
125
126    private java.security.cert.X509Certificate cert;
127
128    private javax.security.cert.X509Certificate tbt_cert;
129
130    private java.security.cert.X509Certificate javaCert;
131
132    private Provider myProvider;
133
134    private javax.security.cert.X509Certificate javaxCert;
135
136    private java.security.cert.Certificate javaSSCert;
137
138    private Provider mySSProvider;
139
140    private Certificate javaxSSCert;
141
142    @Override
143    protected void setUp() throws Exception {
144        try {
145            ByteArrayInputStream bais = new ByteArrayInputStream(base64cert
146                    .getBytes());
147            CertificateFactory cf = CertificateFactory.getInstance("X.509");
148            this.cert = (java.security.cert.X509Certificate) cf
149                    .generateCertificate(bais);
150            this.tbt_cert = X509Certificate.getInstance(cert.getEncoded());
151
152            // non self signed cert
153            this.javaCert = (java.security.cert.X509Certificate)cf
154                    .generateCertificate(new ByteArrayInputStream(selfSignedCert.getBytes()));
155            this.javaxCert = X509Certificate.getInstance(javaCert.getEncoded());
156            myProvider = cf.getProvider();
157            Security.addProvider(myProvider);
158
159            // self signed cert
160            this.javaSSCert = cf.generateCertificate(new ByteArrayInputStream(
161                    selfSignedCert.getBytes()));
162            this.javaxSSCert = X509Certificate.getInstance(javaCert
163                    .getEncoded());
164            mySSProvider = cf.getProvider();
165            Security.addProvider(mySSProvider);
166
167        } catch (java.security.cert.CertificateException e) {
168            // The requested certificate type is not available.
169            // Test pass..
170            this.cert = null;
171            Logger.global.warning("Error in test setup: Certificate type not supported");
172        } catch (javax.security.cert.CertificateException e) {
173            // The requested certificate type is not available.
174            // Test pass..
175            this.cert = null;
176            Logger.global.warning("Error in test setup: Certificate type not supported");
177        }
178    }
179
180    /**
181     * X509Certificate() constructor testing.
182     * @tests {@link X509Certificate#X509Certificate() }
183     */
184    @TestTargetNew(
185        level = TestLevel.COMPLETE,
186        notes = "",
187        method = "X509Certificate",
188        args = {}
189    )
190    public void testConstructor() {
191        //Direct constructor, check if it throws an exception
192        X509Certificate cert = new MyCertificate();
193    }
194
195    /**
196     * getInstance(InputStream inStream) method testing.
197     */
198    @TestTargetNew(
199        level = TestLevel.COMPLETE,
200        notes = "",
201        method = "getInstance",
202        args = {java.io.InputStream.class}
203    )
204    public void testGetInstance1() {
205        if (this.cert == null) {
206            // The requested certificate type is not available.
207            // Test can not be applied.
208            return;
209        }
210        try {
211            ByteArrayInputStream bais = new ByteArrayInputStream(cert
212                    .getEncoded());
213
214            X509Certificate.getInstance(bais);
215        } catch (java.security.cert.CertificateEncodingException e) {
216            fail("Unexpected CertificateEncodingException was thrown.");
217        } catch (CertificateEncodingException e) {
218            fail("Unexpected CertificateEncodingException was thrown.");
219        } catch (CertificateException e) {
220            // The requested certificate type is not available.
221            // Test pass..
222        }
223
224        // Regression for HARMONY-756
225        try {
226            X509Certificate.getInstance((InputStream) null);
227            fail("No expected CertificateException");
228        } catch (CertificateException e) {
229            // expected;
230        }
231    }
232
233    /**
234     * getInstance(byte[] certData) method testing.
235     * @throws CertificateEncodingException
236     * @throws java.security.cert.CertificateEncodingException
237     */
238    @TestTargetNew(
239        level = TestLevel.COMPLETE,
240        notes = "Verifies CertificateException.",
241        method = "getInstance",
242        args = {byte[].class}
243    )
244    public void testGetInstance2() throws java.security.cert.CertificateEncodingException, CertificateEncodingException {
245        boolean certificateException = false;
246        X509Certificate c = null;
247        if (this.cert == null) {
248            // The requested certificate type is not available.
249            // Test can not be applied.
250            return;
251        }
252        try {
253            c = X509Certificate.getInstance(cert.getEncoded());
254        } catch (java.security.cert.CertificateEncodingException e) {
255            fail("Unexpected CertificateEncodingException was thrown.");
256        } catch (CertificateException e) {
257            // The requested certificate type is not available.
258            // Test pass..
259            certificateException = true;
260
261        }
262
263        if (! certificateException) {
264            assertNotNull(c);
265            assertTrue(Arrays.equals(c.getEncoded(),cert.getEncoded() ));
266        }
267
268        try {
269            X509Certificate.getInstance(new byte[]{(byte) 1 });
270        } catch (CertificateException e) {
271            //ok
272        }
273
274        // Regression for HARMONY-756
275        try {
276            X509Certificate.getInstance((byte[]) null);
277            fail("No expected CertificateException");
278        } catch (CertificateException e) {
279            // expected;
280        }
281
282    }
283
284    /**
285     * checkValidity() method testing.
286     * @throws CertificateNotYetValidException
287     * @throws CertificateExpiredException
288     * @throws java.security.cert.CertificateExpiredException
289     * @throws java.security.cert.CertificateNotYetValidException
290     */
291    @TestTargetNew(
292        level = TestLevel.SUFFICIENT,
293        notes = "Doesn't verify exceptions.",
294        method = "checkValidity",
295        args = {}
296    )
297    public void testCheckValidity1() throws CertificateExpiredException, CertificateNotYetValidException, java.security.cert.CertificateExpiredException, java.security.cert.CertificateNotYetValidException {
298        if (this.cert == null) {
299            // The requested certificate type is not available.
300            // Test can not be applied.
301            return;
302        }
303        Date date = new Date();
304        Date nb_date = tbt_cert.getNotBefore();
305        Date na_date = tbt_cert.getNotAfter();
306        try {
307            tbt_cert.checkValidity();
308            assertFalse("CertificateExpiredException expected", date
309                    .compareTo(na_date) > 0);
310            assertFalse("CertificateNotYetValidException expected", date
311                    .compareTo(nb_date) < 0);
312        } catch (CertificateExpiredException e) {
313            assertTrue("Unexpected CertificateExpiredException was thrown",
314                    date.compareTo(na_date) > 0);
315        } catch (CertificateNotYetValidException e) {
316            assertTrue("Unexpected CertificateNotYetValidException was thrown",
317                    date.compareTo(nb_date) < 0);
318        }
319
320       try {
321       tbt_cert.checkValidity();
322       } catch (CertificateExpiredException e) {
323        // ok
324       }
325
326       try {
327            cert.checkValidity();
328        } catch (java.security.cert.CertificateExpiredException e) {
329            // ok
330        }
331
332    }
333
334    /**
335     * checkValidity(Date date) method testing.
336     * @throws CertificateNotYetValidException
337     * @throws CertificateExpiredException
338     */
339    @TestTargetNew(
340        level = TestLevel.COMPLETE,
341        notes = "Doesn't verify exceptions.",
342        method = "checkValidity",
343        args = {java.util.Date.class}
344    )
345    public void testCheckValidity2() throws CertificateNotYetValidException, CertificateExpiredException {
346        if (this.cert == null) {
347            // The requested certificate type is not available.
348            // Test can not be applied.
349            return;
350        }
351        Date[] date = new Date[4];
352        Calendar calendar = Calendar.getInstance();
353        for (int i = 0; i < date.length; i++) {
354            calendar.set(i * 50, Calendar.JANUARY, 1);
355            date[i] = calendar.getTime();
356        }
357        Date nb_date = tbt_cert.getNotBefore();
358        Date na_date = tbt_cert.getNotAfter();
359        for (int i = 0; i < date.length; i++) {
360            try {
361                tbt_cert.checkValidity(date[i]);
362                assertFalse("CertificateExpiredException expected", date[i]
363                        .compareTo(na_date) > 0);
364                assertFalse("CertificateNotYetValidException expected", date[i]
365                        .compareTo(nb_date) < 0);
366            } catch (CertificateExpiredException e) {
367                assertTrue("Unexpected CertificateExpiredException was thrown",
368                        date[i].compareTo(na_date) > 0);
369            } catch (CertificateNotYetValidException e) {
370                assertTrue("Unexpected CertificateNotYetValidException "
371                        + "was thrown", date[i].compareTo(nb_date) < 0);
372            }
373        }
374
375        Calendar calendarNow = Calendar.getInstance();
376
377        try {
378            tbt_cert.checkValidity(calendarNow.getTime());
379        } catch (CertificateExpiredException e) {
380            //ok
381        }
382
383        Calendar calendarPast = GregorianCalendar.getInstance();
384        calendarPast.clear();
385
386        try {
387            tbt_cert.checkValidity(calendarPast.getTime());
388        } catch (CertificateNotYetValidException e) {
389            //ok
390        }
391
392    }
393
394    /**
395     * getVersion() method testing.
396     */
397    @TestTargetNew(
398        level = TestLevel.COMPLETE,
399        notes = "",
400        method = "getVersion",
401        args = {}
402    )
403    public void testGetVersion() {
404        if (this.cert == null) {
405            // The requested certificate type is not available.
406            // Test can not be applied.
407            return;
408        }
409        assertEquals("The version is not correct.", tbt_cert.getVersion(), 2);
410    }
411
412    /**
413     * getSerialNumber() method testing.
414     */
415    @TestTargetNew(
416        level = TestLevel.COMPLETE,
417        notes = "",
418        method = "getSerialNumber",
419        args = {}
420    )
421    public void testGetSerialNumber() {
422        if (this.cert == null) {
423            // The requested certificate type is not available.
424            // Test can not be applied.
425            return;
426        }
427        assertEquals("The serial number is not correct.", tbt_cert
428                .getSerialNumber(), cert.getSerialNumber());
429    }
430
431    /**
432     * getIssuerDN() method testing.
433     */
434    @TestTargetNew(
435        level = TestLevel.SUFFICIENT,
436        notes = "Denigrated API",
437        method = "getIssuerDN",
438        args = {}
439    )
440    public void testGetIssuerDN() {
441        if (this.cert == null) {
442            // The requested certificate type is not available.
443            // Test can not be applied.
444            Logger.global.warning("testGetIssuerDN: error in test setup.");
445        }
446        assertEquals("The issuer DN is not correct.", tbt_cert.getIssuerDN(),
447                cert.getIssuerDN());
448    }
449
450    /**
451     * getSubjectDN() method testing.
452     */
453    @TestTargetNew(
454        level = TestLevel.COMPLETE,
455        notes = "",
456        method = "getSubjectDN",
457        args = {}
458    )
459    public void testGetSubjectDN() {
460        if (this.cert == null) {
461            // The requested certificate type is not available.
462            // Test can not be applied.
463            return;
464        }
465        assertEquals("The subject DN is not correct.", tbt_cert.getSubjectDN(),
466                cert.getSubjectDN());
467    }
468
469    /**
470     * getNotBefore() method testing.
471     */
472    @TestTargetNew(
473        level = TestLevel.COMPLETE,
474        notes = "",
475        method = "getNotBefore",
476        args = {}
477    )
478    public void testGetNotBefore() {
479        if (this.cert == null) {
480            // The requested certificate type is not available.
481            // Test can not be applied.
482            return;
483        }
484        assertEquals("The NotBefore date is not correct.", tbt_cert
485                .getNotBefore(), cert.getNotBefore());
486    }
487
488    /**
489     * getNotAfter() method testing.
490     */
491    @TestTargetNew(
492        level = TestLevel.COMPLETE,
493        notes = "",
494        method = "getNotAfter",
495        args = {}
496    )
497    public void testGetNotAfter() {
498        if (this.cert == null) {
499            // The requested certificate type is not available.
500            // Test can not be applied.
501            return;
502        }
503        assertEquals("The NotAfter date is not correct.", tbt_cert
504                .getNotAfter(), cert.getNotAfter());
505    }
506
507    /**
508     * getSigAlgName() method testing.
509     */
510    @TestTargetNew(
511        level = TestLevel.COMPLETE,
512        notes = "",
513        method = "getSigAlgName",
514        args = {}
515    )
516    public void testGetSigAlgName() {
517        if (this.cert == null) {
518            // The requested certificate type is not available.
519            // Test can not be applied.
520            return;
521        }
522        assertEquals("The name of signature algorithm is not correct.",
523                tbt_cert.getSigAlgName(), cert.getSigAlgName());
524    }
525
526    /**
527     * getSigAlgOID() method testing.
528     */
529    @TestTargetNew(
530        level = TestLevel.COMPLETE,
531        notes = "",
532        method = "getSigAlgOID",
533        args = {}
534    )
535    public void testGetSigAlgOID() {
536        if (this.cert == null) {
537            // The requested certificate type is not available.
538            // Test can not be applied.
539            return;
540        }
541        assertEquals("The name of OID of signature algorithm is not correct.",
542                tbt_cert.getSigAlgOID(), cert.getSigAlgOID());
543    }
544
545    /**
546     * getSigAlgParams() method testing.
547     */
548    @TestTargetNew(
549        level = TestLevel.COMPLETE,
550        notes = "",
551        method = "getSigAlgParams",
552        args = {}
553    )
554    public void testGetSigAlgParams() {
555        if (this.cert == null) {
556            // The requested certificate type is not available.
557            // Test can not be applied.
558            return;
559        }
560        assertTrue("The byte array with encoded algorithm parameters "
561                + "is not correct.", Arrays.equals(tbt_cert.getSigAlgParams(),
562                cert.getSigAlgParams()));
563    }
564
565    /**
566     * The stub class used for testing of non abstract methods.
567     */
568    private class MyCertificate extends X509Certificate {
569
570        public MyCertificate() {
571            super();
572        }
573
574        @Override
575        public void checkValidity() throws CertificateExpiredException,
576                CertificateNotYetValidException {
577        }
578
579        @Override
580        public void checkValidity(Date arg0)
581                throws CertificateExpiredException,
582                CertificateNotYetValidException {
583        }
584
585        @Override
586        public Principal getIssuerDN() {
587            return null;
588        }
589
590        @Override
591        public Date getNotAfter() {
592            return null;
593        }
594
595        @Override
596        public Date getNotBefore() {
597            return null;
598        }
599
600        @Override
601        public BigInteger getSerialNumber() {
602            return null;
603        }
604
605        @Override
606        public String getSigAlgName() {
607            return null;
608        }
609
610        @Override
611        public String getSigAlgOID() {
612            return null;
613        }
614
615        @Override
616        public byte[] getSigAlgParams() {
617            return null;
618        }
619
620        @Override
621        public Principal getSubjectDN() {
622            return null;
623        }
624
625        @Override
626        public int getVersion() {
627            return 0;
628        }
629
630        @Override
631        public byte[] getEncoded() throws CertificateEncodingException {
632            return null;
633        }
634
635        @Override
636        public PublicKey getPublicKey() {
637            return null;
638        }
639
640        @Override
641        public String toString() {
642            return null;
643        }
644
645        @Override
646        public void verify(PublicKey key) throws CertificateException,
647                NoSuchAlgorithmException, InvalidKeyException,
648                NoSuchProviderException, SignatureException {
649        }
650
651        @Override
652        public void verify(PublicKey key, String sigProvider)
653                throws CertificateException, NoSuchAlgorithmException,
654                InvalidKeyException, NoSuchProviderException,
655                SignatureException {
656        }
657    }
658
659    public class MyModifiablePublicKey implements PublicKey {
660
661        private PublicKey key;
662        private boolean modifiedAlgo;
663        private String algo;
664        private String format;
665        private boolean modifiedFormat;
666        private boolean modifiedEncoding;
667        private byte[] encoding;
668
669        public MyModifiablePublicKey(PublicKey k) {
670            super();
671            this.key = k;
672        }
673
674        public String getAlgorithm() {
675            if (modifiedAlgo) {
676                return algo;
677            } else {
678                return key.getAlgorithm();
679            }
680        }
681
682        public String getFormat() {
683            if (modifiedFormat) {
684                return this.format;
685            } else {
686                return key.getFormat();
687            }
688
689        }
690
691        public byte[] getEncoded() {
692            if (modifiedEncoding) {
693                return this.encoding;
694            } else {
695                return key.getEncoded();
696            }
697
698        }
699
700        public long getSerVerUID() {
701            return key.serialVersionUID;
702        }
703
704        public void setAlgorithm(String myAlgo) {
705            modifiedAlgo = true;
706            this.algo = myAlgo;
707        }
708
709        public void setFormat(String myFormat) {
710            modifiedFormat = true;
711            format = myFormat;
712        }
713
714        public void setEncoding(byte[] myEncoded) {
715            modifiedEncoding = true;
716            encoding = myEncoded;
717        }
718    }
719
720    /**
721     * @throws CertificateEncodingException
722     * @tests {@link Certificate#getEncoded()}
723     */
724    @TestTargetNew(
725      level = TestLevel.SUFFICIENT,
726      notes = "No ASN1/DER encoder available. Exception is not supported.",
727      method = "getEncoded",
728      args = {}
729    )
730    public void testGetEncoded()
731            throws CertificateEncodingException, java.security.cert.CertificateException {
732        // cert = DER encoding of the ASN1.0 structure
733        assertTrue(Arrays.equals(cert.getEncoded(), tbt_cert.getEncoded()));
734        assertFalse(Arrays.equals(javaxCert.getEncoded(), tbt_cert.getEncoded()));
735    }
736
737    /**
738     * @tests {@link Certificate#getPublicKey()}
739     */
740    @TestTargetNew(
741      level = TestLevel.COMPLETE,
742      notes = "",
743      method = "getPublicKey",
744      args = {}
745    )
746    public void testGetPublicKey() {
747       PublicKey key = javaxCert.getPublicKey();
748       assertNotNull(key);
749       assertEquals(javaxCert.getPublicKey(), javaCert.getPublicKey());
750       assertEquals(key.getAlgorithm(),"RSA");
751
752       key = javaxSSCert.getPublicKey();
753       assertNotNull(key);
754       assertEquals(key.getAlgorithm(),"RSA");
755
756       //assertTrue(mySSProvider.containsKey(key));
757
758    }
759
760    /**
761     * @throws SignatureException
762     * @throws NoSuchProviderException
763     * @throws NoSuchAlgorithmException
764     * @throws InvalidKeyException
765     * @throws CertificateException
766     * @tests {@link Certificate#verify(PublicKey)}
767     */
768    @TestTargetNew(
769      level = TestLevel.SUFFICIENT,
770      notes = " CertificateException not supported."+
771              "NoSuchAlgorithmException, NoSuchProviderException can be "+
772              "implemented only with working Cert. Verification fails "+
773              "(see failing) precondition assertions",
774      method = "verify",
775      args = {java.security.PublicKey.class}
776    )
777    @SideEffect("Destroys MD5 provider, hurts succeeding tests")
778    public void testVerifyPublicKey() throws InvalidKeyException,
779            NoSuchAlgorithmException, NoSuchProviderException,
780            SignatureException, CertificateException {
781
782        // Preconditions
783        assertNotNull(javaxCert.getPublicKey());
784        assertNotNull(javaxSSCert.getPublicKey());
785        //precondition for self signed certificates
786        /*assertEquals(((X509Certificate) javaxSSCert).getIssuerDN().getName(),
787                ((X509Certificate) javaxSSCert).getSubjectDN());*/
788
789        // must always evaluate true for self signed
790        // here not self signed:
791        try {
792            javaxCert.verify(javaxCert.getPublicKey());
793        } catch (SignatureException e) {
794            // ok
795        }
796
797        PublicKey k = javaxCert.getPublicKey();
798
799        MyModifiablePublicKey changedEncoding = new MyModifiablePublicKey(k);
800        changedEncoding
801                .setEncoding(new byte[javaxCert.getEncoded().length - 1]);
802
803        try {
804            javaxCert.verify(tbt_cert.getPublicKey());
805        } catch (InvalidKeyException e) {
806            // ok
807        }
808
809
810        try {
811            javaxCert.verify(null);
812        } catch (Exception e) {
813            // ok
814        }
815
816        try {
817            javaxCert.verify(changedEncoding);
818            fail("Exception expected");
819        } catch (Exception e) {
820            // ok
821        }
822
823        // following test doesn't work because the algorithm is derived from
824        // somewhere else.
825
826        // MyModifiablePublicKey changedAlgo = new MyModifiablePublicKey(k);
827        // changedAlgo.setAlgorithm("MD5withBla");
828
829        // try {
830        //     javaxCert.verify(changedAlgo);
831        //     fail("Exception expected");
832        // } catch (SignatureException e) {
833        //     // ok
834        // }
835
836        // Security.removeProvider(mySSProvider.getName());
837
838        // try {
839        //     javaxSSCert.verify(javaxSSCert.getPublicKey());
840        // } catch (NoSuchProviderException e) {
841        //     // ok
842        // }
843
844        // Security.addProvider(mySSProvider);
845
846        // must always evaluate true for self signed
847        // javaxSSCert.verify(javaxSSCert.getPublicKey());
848    }
849
850    /**
851     * @throws SignatureException
852     * @throws NoSuchProviderException
853     * @throws NoSuchAlgorithmException
854     * @throws java.security.cert.CertificateException
855     * @throws InvalidKeyException
856     * @throws IOException
857     * @throws CertificateException
858     * @tests {@link Certificate#verify(PublicKey, String)}
859     */
860    @TestTargetNew(
861      level = TestLevel.SUFFICIENT,
862      notes = "",
863      method = "verify",
864      args = {java.security.PublicKey.class, java.lang.String.class}
865    )
866    @SideEffect("Destroys MD5 provider, hurts succeeding tests")
867    public void testVerifyPublicKeyString() throws InvalidKeyException,
868            java.security.cert.CertificateException, NoSuchAlgorithmException,
869            NoSuchProviderException, SignatureException, IOException,
870            CertificateException {
871
872        try {
873            javaxCert.verify(javaxCert.getPublicKey(), myProvider.getName());
874        } catch (NoSuchAlgorithmException e) {
875            // ok
876        }
877
878        // myProvider.getService(type, algorithm)
879
880        Security.removeProvider(myProvider.getName());
881        try {
882            javaxCert.verify(javaxCert.getPublicKey(), myProvider.getName());
883        } catch (NoSuchProviderException e) {
884            // ok
885        }
886        Security.addProvider(myProvider);
887
888        Provider[] providers = Security.getProviders("Signature.MD5withRSA");
889        if (providers == null || providers.length == 0) {
890            fail("no Provider for Signature.MD5withRSA");
891            return;
892        }
893
894        // self signed cert: should verify with provider
895        try {
896            javaxSSCert.verify(javaxSSCert.getPublicKey(),
897                    providers[0].getName());
898        } catch (SignatureException e) {
899            fail("blu");
900        }
901
902    }
903
904    public static Test suite() {
905        return new TestSuite(X509CertificateTest.class);
906    }
907
908    public static void main(String[] args) {
909        junit.textui.TestRunner.run(suite());
910    }
911}
912