X509CertImplTest.java revision 561ee011997c6c2f1befbfaa9d5f0a99771c1d63
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* @author Alexander Y. Kleymenov
19*/
20
21package org.apache.harmony.security.tests.provider.cert;
22
23import java.io.ByteArrayInputStream;
24import java.io.IOException;
25import java.math.BigInteger;
26import java.security.KeyPair;
27import java.security.KeyPairGenerator;
28import java.security.PrivateKey;
29import java.security.PublicKey;
30import java.security.Signature;
31import java.security.cert.CertificateEncodingException;
32import java.security.cert.CertificateExpiredException;
33import java.security.cert.CertificateNotYetValidException;
34import java.security.cert.CertificateParsingException;
35import java.security.cert.X509Certificate;
36import java.util.Arrays;
37import java.util.Collection;
38import java.util.Date;
39import java.util.Iterator;
40import java.util.List;
41import java.util.Set;
42
43import javax.security.auth.x500.X500Principal;
44
45import junit.framework.Test;
46import junit.framework.TestCase;
47import junit.framework.TestSuite;
48
49import org.apache.harmony.security.asn1.ObjectIdentifier;
50import org.apache.harmony.security.provider.cert.X509CertImpl;
51import org.apache.harmony.security.tests.support.cert.TestUtils;
52import org.apache.harmony.security.x501.Name;
53import org.apache.harmony.security.x509.AlgorithmIdentifier;
54import org.apache.harmony.security.x509.AlternativeName;
55import org.apache.harmony.security.x509.AuthorityKeyIdentifier;
56import org.apache.harmony.security.x509.BasicConstraints;
57import org.apache.harmony.security.x509.CRLDistributionPoints;
58import org.apache.harmony.security.x509.Certificate;
59import org.apache.harmony.security.x509.CertificatePolicies;
60import org.apache.harmony.security.x509.DistributionPoint;
61import org.apache.harmony.security.x509.DistributionPointName;
62import org.apache.harmony.security.x509.ExtendedKeyUsage;
63import org.apache.harmony.security.x509.Extension;
64import org.apache.harmony.security.x509.Extensions;
65import org.apache.harmony.security.x509.GeneralName;
66import org.apache.harmony.security.x509.GeneralNames;
67import org.apache.harmony.security.x509.GeneralSubtree;
68import org.apache.harmony.security.x509.GeneralSubtrees;
69import org.apache.harmony.security.x509.InhibitAnyPolicy;
70import org.apache.harmony.security.x509.KeyUsage;
71import org.apache.harmony.security.x509.NameConstraints;
72import org.apache.harmony.security.x509.PolicyConstraints;
73import org.apache.harmony.security.x509.PolicyInformation;
74import org.apache.harmony.security.x509.ReasonFlags;
75import org.apache.harmony.security.x509.SubjectKeyIdentifier;
76import org.apache.harmony.security.x509.SubjectPublicKeyInfo;
77import org.apache.harmony.security.x509.TBSCertificate;
78import org.apache.harmony.security.x509.Validity;
79
80/**
81 * X509CertImplTest
82 */
83public class X509CertImplTest extends TestCase {
84
85    //
86    // The values of certificate's fields:
87    //
88
89    int         version         = 2; //v3
90    BigInteger  serialNumber    = BigInteger.valueOf(555L);
91
92    // Algorithm name and its OID (http://oid.elibel.tm.fr)
93    String      algOID          = "1.2.840.10040.4.3";
94    String      algName         = "SHA1withDSA";
95
96    // DER boolean false encoding (http://asn1.elibel.tm.fr)
97    // Makes no sense. For testing purposes we need just provide
98    // some ASN.1 structure:
99    byte[]      algParams       = {1, 1, 0};
100    String      issuerName      = "O=Certificate Issuer";
101    long        notBefore       = 1000000000L;
102    long        notAfter        = 2000000000L;
103    String      subjectName     = "O=Subject Organization";
104
105    // keys are using to make signature and to verify it
106    static PublicKey   publicKey;
107    static PrivateKey  privateKey;
108    byte[]      key             = new byte[] {1, 2, 3, 4, 5, 6, 7, 8}; // random value
109    byte[]      keyEncoding     = null;
110    boolean[]   issuerUniqueID  = new boolean[]
111                {true, false, true, false, true, false, true, false}; // random value
112    boolean[]   subjectUniqueID = new boolean[]
113                {false, true, false, true, false, true, false, true}; // random value
114
115    // Extensions' values
116    byte[]      extValEncoding  = new byte[] {1, 1, 1}; // random value
117    boolean[]   extnKeyUsage    = new boolean[]
118                {true, false, true, false, true, false, true, false, true}; // random value
119    List    extnExtendedKeyUsage = Arrays.asList(new int[][] {
120
121        // Extended key usage values as specified in rfc 3280
122        // (http://www.ietf.org/rfc/rfc3280.txt):
123        ObjectIdentifier.toIntArray("2.5.29.37.0"),       // Any extended key usage
124        ObjectIdentifier.toIntArray("1.3.6.1.5.5.7.3.1"), // TLS Web server authentication
125        ObjectIdentifier.toIntArray("1.3.6.1.5.5.7.3.1"), // TLS Web server authentication
126        ObjectIdentifier.toIntArray("1.3.6.1.5.5.7.3.2"), // TLS Web client authentication
127        ObjectIdentifier.toIntArray("1.3.6.1.5.5.7.3.3"), // Code Signing
128        ObjectIdentifier.toIntArray("1.3.6.1.5.5.7.3.4"), // E-mail protection
129        ObjectIdentifier.toIntArray("1.3.6.1.5.5.7.3.5"), // IP security end system
130        ObjectIdentifier.toIntArray("1.3.6.1.5.5.7.3.6"), // IP security tunnel termination
131        ObjectIdentifier.toIntArray("1.3.6.1.5.5.7.3.7"), // IP security user
132        ObjectIdentifier.toIntArray("1.3.6.1.5.5.7.3.8"), // Timestamping
133        ObjectIdentifier.toIntArray("1.3.6.1.5.5.7.3.9"), // OCSP signing
134        ObjectIdentifier.toIntArray("1.3.6.1.5.5.8.2.2"), // iKEIntermediate
135        ObjectIdentifier.toIntArray("1.3.6.1.4.1.311.10.3.3"), // MS Server Gated Cryptography
136        ObjectIdentifier.toIntArray("2.16.840.1.113730.4.1"), // Netscape Server Gated Cryptography
137    });
138    static NameConstraints nameConstraints;
139    int extnBCLen = 5;
140    static GeneralNames extnSANames;
141    static GeneralNames extnIANames;
142
143    static {
144        try {
145            extnSANames = new GeneralNames(
146                Arrays.asList(new GeneralName[] {
147                    new GeneralName(1, "rfc@822.Name"),
148                    new GeneralName(2, "dNSName"),
149                    new GeneralName(4, "O=Organization"),
150                    new GeneralName(6, "http://uniform.Resource.Id"),
151                    new GeneralName(7, "255.255.255.0"),
152                    new GeneralName(8, "1.2.3.4444.55555")
153            }));
154            GeneralSubtrees permittedNames = new GeneralSubtrees()
155                    .addSubtree(new GeneralSubtree(
156                            new GeneralName(1, "rfc@822.Name"), 1, 2))
157                    .addSubtree(new GeneralSubtree(
158                            new GeneralName(2, "dNSName")))
159                    .addSubtree(new GeneralSubtree(
160                            new GeneralName(8, "1.2.3.4444.55555"), 2));
161            GeneralSubtrees excludedNames = new GeneralSubtrees()
162                    .addSubtree(new GeneralSubtree(
163                            new GeneralName(1, "rfc@822.BadName"), 1, 2))
164                    .addSubtree(new GeneralSubtree(
165                            new GeneralName(2, "BadDNSName")))
166                    .addSubtree(new GeneralSubtree(
167                            new GeneralName(8, "2.3.4.4444.222"), 2));
168            nameConstraints =
169                new NameConstraints(permittedNames, excludedNames);
170        } catch (IOException e) {
171            // should not be thrown
172            e.printStackTrace();
173            extnSANames = new GeneralNames();
174            nameConstraints = new NameConstraints();
175        }
176        extnIANames = extnSANames;
177
178        try {
179            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
180            keyGen.initialize(1024);
181            KeyPair keyPair = keyGen.genKeyPair();
182            publicKey = keyPair.getPublic();
183            privateKey = keyPair.getPrivate();
184        } catch (Exception e) {
185            e.printStackTrace();
186        }
187    }
188
189    // Extensions
190    Extension[] extensions      = new Extension[] {
191
192        // Supported critical extensions (as specified in rfc 3280
193        // http://www.ietf.org/rfc/rfc3280.txt):
194        // Key Usage
195        new Extension("2.5.29.15", true, new KeyUsage(extnKeyUsage)),
196        // Basic Constraints
197        new Extension("2.5.29.19", true, new BasicConstraints(true, extnBCLen)),
198        // Certificate Policies with ANY policy
199        new Extension("2.5.29.32", true,
200                new CertificatePolicies()
201                .addPolicyInformation(new PolicyInformation("2.5.29.32.0"))),
202        // Subject Alternative Name
203        new Extension("2.5.29.17", true,
204                new AlternativeName(AlternativeName.SUBJECT, extnSANames)),
205        // Name Constraints
206        new Extension("2.5.29.30", true, nameConstraints),
207        // Policy Constraints
208        new Extension("2.5.29.36", true, new PolicyConstraints(1, 2)),
209        // Extended Key Usage
210        new Extension("2.5.29.37", true, new ExtendedKeyUsage(extnExtendedKeyUsage)),
211        // Inhibit Any-Policy
212        new Extension("2.5.29.54", true, new InhibitAnyPolicy(1)),
213
214
215        // Unsupported critical extensions:
216        new Extension("1.2.77.777", true, extValEncoding),
217
218
219        // Non-critical extensions (as specified in rfc 3280
220        // http://www.ietf.org/rfc/rfc3280.txt):
221
222        // Issuer Alternative Name
223        new Extension("2.5.29.18", false,
224                new AlternativeName(AlternativeName.ISSUER, extnSANames)),
225        // CRL Distribution Points
226        new Extension("2.5.29.31", false,
227                new CRLDistributionPoints(Arrays.asList(new DistributionPoint[] {
228                    new DistributionPoint(
229                        new DistributionPointName(extnSANames),
230                        new ReasonFlags(extnKeyUsage),
231                        extnSANames
232                        ),
233                }))),
234        // Authority Key Identifier
235        new Extension("2.5.29.35", false,
236                new AuthorityKeyIdentifier(
237                    // random value for key identifier
238                    new byte[] {1, 2, 3, 4, 5}, extnSANames, serialNumber)),
239        // Subject Key Identifier
240        new Extension("2.5.29.14", false,
241                // random value for key identifier
242                new SubjectKeyIdentifier(new byte[] {1, 2, 3, 4, 5})),
243        // Policy Mappings
244        new Extension("2.5.29.33", false, extValEncoding),
245    };
246    List allCritical = Arrays.asList(new String[] {"2.5.29.15", "2.5.29.19",
247        "2.5.29.32", "2.5.29.17", "2.5.29.30", "2.5.29.36", "2.5.29.37",
248        "2.5.29.54", "1.2.77.777"});
249    List allNonCritical = Arrays.asList(new String[] {"2.5.29.18", "2.5.29.35",
250        "2.5.29.14", "2.5.29.33", "2.5.29.31"});
251
252    public X509Certificate certificate;
253    byte[] tbsCertEncoding;
254    byte[] signatureValue;
255    // to minimize efforts on signature generation the signature will be
256    // stored in this field
257    static byte[] signatureValueBytes;
258    byte[] certEncoding;
259
260    /**
261     * Creates the master certificate on the base of which
262     * all functionality will be tested.
263     * @return
264     * @throws java.lang.Exception
265     */
266    protected void setUp() throws java.lang.Exception {
267        AlgorithmIdentifier signature =
268            new AlgorithmIdentifier(algOID, algParams);
269        Name issuer = new Name(issuerName);
270        Name subject = new Name(subjectName);
271        Validity validity =
272            new Validity(new Date(notBefore), new Date(notAfter));
273
274        SubjectPublicKeyInfo subjectPublicKeyInfo = (SubjectPublicKeyInfo)
275            SubjectPublicKeyInfo.ASN1.decode(publicKey.getEncoded());
276        keyEncoding = subjectPublicKeyInfo.getEncoded();
277
278        Extensions exts = new Extensions(Arrays.asList(extensions));
279
280        TBSCertificate tbsCertificate =
281            new TBSCertificate(version, serialNumber,
282                signature, issuer, validity, subject, subjectPublicKeyInfo,
283                issuerUniqueID, subjectUniqueID, exts);
284        tbsCertEncoding = tbsCertificate.getEncoded();
285
286        if (signatureValueBytes == null) {
287            try {
288                Signature sig= Signature.getInstance("DSA");//new byte[32];
289                sig.initSign(privateKey);
290                sig.update(tbsCertEncoding, 0, tbsCertEncoding.length);
291                signatureValueBytes = sig.sign();
292            } catch (Exception e) {
293                e.printStackTrace();
294                signatureValueBytes = new byte[10];
295            }
296        }
297        if ("testVerify3".equals(getName())) {
298            signatureValue = new byte[signatureValueBytes.length];
299            // make incorrect signature value:
300            System.arraycopy(signatureValueBytes, 0,
301                    signatureValue, 0, signatureValueBytes.length);
302            signatureValue[20]++;
303        } else {
304            signatureValue = signatureValueBytes;
305        }
306
307        Certificate cert =
308            new Certificate(tbsCertificate, signature, signatureValue);
309
310        certEncoding = cert.getEncoded();
311
312        cert = (Certificate) Certificate.ASN1.decode(certEncoding);
313        certificate = new X509CertImpl(cert);
314    }
315
316    public void testCreation() throws Exception {
317        ByteArrayInputStream bis = new ByteArrayInputStream(certEncoding);
318        certificate = new X509CertImpl(bis);
319    }
320
321    /**
322     * checkValidity() method testing.
323     */
324    public void testCheckValidity1() {
325        try {
326            certificate.checkValidity();
327            fail("CertificateExpiredException should be thrown.");
328        } catch (CertificateNotYetValidException e) {
329            fail("Unexpected CertificateNotYetValidException was thrown.");
330        } catch (CertificateExpiredException e) {
331        }
332    }
333
334    /**
335     * checkValidity(Date date) method testing.
336     */
337    public void testCheckValidity2() {
338        try {
339            certificate.checkValidity(new Date(3000000000L));
340            fail("CertificateExpiredException should be thrown.");
341        } catch (CertificateNotYetValidException e) {
342            fail("Unexpected CertificateNotYetValidException was thrown.");
343        } catch (CertificateExpiredException e) {
344        }
345        try {
346            certificate.checkValidity(new Date(100000000L));
347            fail("CertificateNotYetValidException be thrown.");
348        } catch (CertificateExpiredException e) {
349            fail("Unexpected CertificateExpiredException was thrown.");
350        } catch (CertificateNotYetValidException e) {
351        }
352        try {
353            certificate.checkValidity(new Date(1000000000L));
354            certificate.checkValidity(new Date(1500000000L));
355            certificate.checkValidity(new Date(2000000000L));
356        } catch (CertificateExpiredException e) {
357            fail("Unexpected CertificateExpiredException was thrown.");
358        } catch (CertificateNotYetValidException e) {
359            fail("Unexpected CertificateNotYetValidException was thrown.");
360        }
361    }
362
363    /**
364     * @tests java.security.cert.X509Certificate#getVersion()
365     */
366    public void testGetVersion() throws IOException {
367
368        byte[] x509CertEnc = TestUtils.getX509Certificate_v1();
369
370        // test initial version that is 1
371        assertEquals("Version 1:", 1, new X509CertImpl(x509CertEnc)
372                .getVersion());
373
374        // as fas as we know offset of version byte in the cert. encoding
375        // it is possible to change it to test other versions
376
377        // offset of version byte in certificate encoding
378        int offset = 8;
379
380        // set version to 2
381        x509CertEnc[offset] = 1;
382        assertEquals("Version 2:", 2, new X509CertImpl(x509CertEnc)
383                .getVersion());
384
385        // set version to 3
386        x509CertEnc[offset] = 2;
387        assertEquals("Version 3:", 3, new X509CertImpl(x509CertEnc)
388                .getVersion());
389    }
390
391    /**
392     * getSerialNumber() method testing.
393     */
394    public void testGetSerialNumber() {
395        assertEquals("Incorrect value of version",
396                serialNumber, certificate.getSerialNumber());
397    }
398
399    /**
400     * getIssuerDN() method testing.
401     */
402    public void testGetIssuerDN() {
403        assertEquals("Incorrect issuer",
404                new X500Principal(issuerName).getName(),
405                certificate.getIssuerDN().getName());
406    }
407
408    /**
409     * getIssuerX500Principal() method testing.
410     */
411    public void testGetIssuerX500Principal() {
412        assertEquals("Incorrect issuer",
413                new X500Principal(issuerName),
414                certificate.getIssuerX500Principal());
415    }
416
417    /**
418     * getSubjectDN() method testing.
419     */
420    public void testGetSubjectDN() {
421        assertEquals("Incorrect subject",
422                new X500Principal(subjectName).getName(),
423                certificate.getSubjectDN().getName());
424    }
425
426    /**
427     * getSubjectX500Principal() method testing.
428     */
429    public void testGetSubjectX500Principal() {
430        assertEquals("Incorrect subject",
431                new X500Principal(subjectName),
432                certificate.getSubjectX500Principal());
433    }
434
435    /**
436     * getNotBefore() method testing.
437     */
438    public void testGetNotBefore() {
439        assertEquals("Incorrect notBefore date",
440                new Date(notBefore), certificate.getNotBefore());
441    }
442
443    /**
444     * getNotAfter() method testing.
445     */
446    public void testGetNotAfter() {
447        assertEquals("Incorrect notAfter date",
448                new Date(notAfter), certificate.getNotAfter());
449    }
450
451    public static void printAsHex(int perLine, String prefix,
452                                        String delimiter, byte[] data) {
453        for (int i=0; i<data.length; i++) {
454            String tail = Integer.toHexString(0x000000ff & data[i]);
455            if (tail.length() == 1) {
456                tail = "0" + tail;
457            }
458            System.out.print(prefix + "0x" + tail + delimiter);
459
460            if (((i+1)%perLine) == 0) {
461                System.out.println();
462            }
463        }
464        System.out.println();
465    }
466
467    /**
468     * getTBSCertificate() method testing.
469     */
470    public void testGetTBSCertificate() {
471        try {
472            if (!Arrays.equals(
473                        tbsCertEncoding, certificate.getTBSCertificate())) {
474                System.out.println("TBSCertificate encoding missmatch:");
475                System.out.println("Expected:");
476                printAsHex(20, "", " ", tbsCertEncoding);
477                System.out.println("Got:");
478                printAsHex(20, "", " ", certificate.getTBSCertificate());
479                fail("Incorrect encoding of TBSCertificate.");
480            }
481        } catch (CertificateEncodingException e) {
482            fail("Unexpected CertificateEncodingException was thrown.");
483        }
484    }
485
486    /**
487     * getSignature() method testing.
488     */
489    public void testGetSignature() {
490        if (!Arrays.equals(signatureValue, certificate.getSignature())) {
491            fail("Incorrect Signature value.");
492        }
493    }
494
495    /**
496     * getSigAlgName() method testing.
497     */
498    public void testGetSigAlgName() {
499        assertEquals("Incorrect value of signature algorithm name",
500                algName, certificate.getSigAlgName());
501    }
502
503    /**
504     * getSigAlgOID() method testing.
505     */
506    public void testGetSigAlgOID() {
507        assertEquals("Incorrect value of signature algorithm OID",
508                algOID, certificate.getSigAlgOID());
509    }
510
511    /**
512     * getSigAlgParams() method testing.
513     */
514    public void testGetSigAlgParams() {
515        if (!Arrays.equals(algParams, certificate.getSigAlgParams())) {
516            fail("Incorrect SigAlgParams value.");
517        }
518    }
519
520    /**
521     * getIssuerUniqueID() method testing.
522     */
523    public void testGetIssuerUniqueID() {
524        if (!Arrays.equals(issuerUniqueID, certificate.getIssuerUniqueID())) {
525            fail("Incorrect issuerUniqueID value.");
526        }
527    }
528
529    /**
530     * getSubjectUniqueID() method testing.
531     */
532    public void testGetSubjectUniqueID() {
533        if (!Arrays.equals(subjectUniqueID, certificate.getSubjectUniqueID())) {
534            fail("Incorrect subjectUniqueID value.");
535        }
536    }
537
538    /**
539     * getKeyUsage() method testing.
540     */
541    public void testGetKeyUsage() {
542        boolean[] ku = certificate.getKeyUsage();
543        if ((ku == null) || (ku.length < extnKeyUsage.length)) {
544            fail("Incorrect Key Usage value.");
545        }
546        for (int i=0; i<extnKeyUsage.length; i++) {
547            if (extnKeyUsage[i] != ku[i]) {
548                fail("Incorrect Key Usage value.");
549            }
550        }
551    }
552
553    /**
554     * getExtendedKeyUsage() method testing.
555     */
556    public void testGetExtendedKeyUsage() throws Exception {
557        List exku = certificate.getExtendedKeyUsage();
558        if ((exku == null)
559                || (exku.size() != extnExtendedKeyUsage.size())) {
560            fail("Incorrect Extended Key Usage value.");
561        }
562        for (int i=0; i<extnExtendedKeyUsage.size(); i++) {
563            String ku = ObjectIdentifier
564                    .toString((int[]) extnExtendedKeyUsage.get(i));
565            if (!exku.contains(ku)) {
566                fail("Missing value:" + ku);
567            }
568        }
569    }
570
571    /**
572     * getBasicConstraints() method testing.
573     */
574    public void testGetBasicConstraints() {
575        assertEquals(extnBCLen, certificate.getBasicConstraints());
576    }
577
578    /**
579     * getSubjectAlternativeNames() method testing.
580     */
581    public void testGetSubjectAlternativeNames() {
582        try {
583            Collection certSans = certificate.getSubjectAlternativeNames();
584            if (certSans == null) {
585                fail("Returned value should not be null.");
586            }
587            List sans = extnSANames.getPairsList();
588            if (sans.size() != certSans.size()) {
589                fail("Size of returned collection does not match to the actual");
590            }
591            Iterator it = certSans.iterator();
592            while (it.hasNext()) {
593                List extnSan = (List) it.next();
594                Integer tag = (Integer) extnSan.get(0);
595                for (int i=0; i< sans.size(); i++) {
596                    List san = (List) sans.get(i);
597                    if (tag.equals(san.get(0))) {
598                        assertEquals(
599                                "Incorrect value of Subject Alternative Name",
600                                extnSan.get(1), san.get(1));
601                    }
602                }
603            }
604        } catch (CertificateParsingException e) {
605            fail("Subject Alternative Name extension was incorrectly encoded.");
606        }
607    }
608
609    /**
610     * getIssuerAlternativeNames() method testing.
611     */
612    public void testGetIssuerAlternativeNames() {
613        try {
614            Collection certIans = certificate.getIssuerAlternativeNames();
615            if (certIans == null) {
616                fail("Returned value should not be null.");
617            }
618            List ians = extnSANames.getPairsList();
619            if (ians.size() != certIans.size()) {
620                fail("Size of returned collection does not match to the actual");
621            }
622            Iterator it = certIans.iterator();
623            while (it.hasNext()) {
624                List extnIan = (List) it.next();
625                Integer tag = (Integer) extnIan.get(0);
626                for (int i=0; i< ians.size(); i++) {
627                    List ian = (List) ians.get(i);
628                    if (tag.equals(ian.get(0))) {
629                        assertEquals(
630                                "Incorrect value of Issuer Alternative Name",
631                                extnIan.get(1), ian.get(1));
632                    }
633                }
634            }
635        } catch (CertificateParsingException e) {
636            fail("Issuer Alternative Name extension was incorrectly encoded.");
637        }
638    }
639
640    /**
641     * getEncoded() method testing.
642     */
643    public void testGetEncoded() {
644        try {
645            if (!Arrays.equals(certEncoding, certificate.getEncoded())) {
646                fail("Incorrect encoding of Certificate.");
647            }
648        } catch (CertificateEncodingException e) {
649            fail("Unexpected CertificateEncodingException was thrown.");
650        }
651    }
652
653    /**
654     * getPublicKey() method testing.
655     */
656    public void testGetPublicKey() {
657        if (!Arrays.equals(keyEncoding, certificate.getPublicKey().getEncoded())) {
658            fail("Incorrect Public Key.");
659        }
660    }
661
662    /**
663     * getExtensionValue(String oid) method testing.
664     */
665    public void testGetExtensionValue() {
666        for (int i=0; i<extensions.length; i++) {
667            String id = extensions[i].getExtnID();
668            byte[] certExtnValue = certificate.getExtensionValue(id);
669            byte[] certExtnValue2Check = extensions[i].getRawExtnValue();
670                certificate.getExtensionValue(id);
671            if (!Arrays.equals(certExtnValue2Check, certExtnValue)) {
672                System.out.println("Extension encoding mismatch for "+id);
673                System.out.println("Expected:");
674                printAsHex(20, "", " ", certExtnValue2Check);
675                System.out.println("But has been got:");
676                if (certExtnValue == null) {
677                    System.out.println("null");
678                } else {
679                    printAsHex(20, "", " ", certExtnValue);
680                }
681                fail("The values for extension "+id+" differ.");
682            }
683        }
684        assertNull("Null value should be returned in the case of "
685                + "nonexisting extension",
686                certificate.getExtensionValue("1.1.1.1"));
687    }
688
689    /**
690     * getCriticalExtensionOIDs() method testing.
691     */
692    public void testGetCriticalExtensionOIDs() {
693        Set certCEOids = certificate.getCriticalExtensionOIDs();
694        if (!(certCEOids.containsAll(allCritical)
695                    && allCritical.containsAll(certCEOids))) {
696            fail("Incorrect value of Critical Extension OIDs");
697        }
698    }
699
700    /**
701     * getNonCriticalExtensionOIDs() method testing.
702     */
703    public void testGetNonCriticalExtensionOIDs() {
704        Set certNCEOids = certificate.getNonCriticalExtensionOIDs();
705        if (!(certNCEOids.containsAll(allNonCritical)
706                    && allNonCritical.containsAll(certNCEOids))) {
707            fail("Incorrect value of Non Critical Extension OIDs");
708        }
709    }
710
711    /**
712     * hasUnsupportedCriticalExtension() method testing.
713     */
714    public void testHasUnsupportedCriticalExtension() {
715        assertTrue("Incorrect value of hasUnsupportedCriticalExtension",
716                certificate.hasUnsupportedCriticalExtension());
717
718        if (!certificate.hasUnsupportedCriticalExtension()) {
719            fail("Incorrect value of hasUnsupportedCriticalExtension");
720        }
721    }
722
723    /**
724     * toString() method testing.
725     */
726    public void testToString() {
727        assertNotNull("String representation should not be null",
728                certificate.toString());
729    }
730
731    /**
732     * TODO
733     * verify(PublicKey key) method testing.
734     */
735    public void testVerify1() throws Exception {
736        certificate.verify(publicKey);
737    }
738
739    /**
740     * TODO
741     * verify(PublicKey key, String sigProvider) method testing.
742     */
743    public void testVerify2() throws Exception {
744        certificate.verify(publicKey, Signature.getInstance("SHA1withDSA")
745                .getProvider().getName());
746    }
747
748    /**
749     * TODO
750     * verify(PublicKey key) method testing.
751     */
752    public void testVerify3() throws Exception {
753        try {
754            certificate.verify(publicKey);
755            fail("Incorrect signature successfully verified.");
756        } catch (Exception e) {
757        }
758    }
759
760    public static Test suite() {
761        return new TestSuite(X509CertImplTest.class);
762    }
763
764    public static void main(String[] args) throws Exception {
765        junit.textui.TestRunner.run(suite());
766    }
767}
768
769