CertificateTest.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/**
19* @author Alexander Y. Kleymenov
20*/
21
22package org.apache.harmony.security.tests.x509;
23
24import java.io.ByteArrayInputStream;
25import java.io.IOException;
26import java.math.BigInteger;
27import java.security.cert.CertificateFactory;
28import java.util.Arrays;
29import java.util.Date;
30
31import junit.framework.Test;
32import junit.framework.TestCase;
33import junit.framework.TestSuite;
34
35import org.apache.harmony.security.asn1.ASN1Integer;
36import org.apache.harmony.security.x501.Name;
37import org.apache.harmony.security.x509.AlgorithmIdentifier;
38import org.apache.harmony.security.x509.Certificate;
39import org.apache.harmony.security.x509.EDIPartyName;
40import org.apache.harmony.security.x509.Extension;
41import org.apache.harmony.security.x509.Extensions;
42import org.apache.harmony.security.x509.GeneralName;
43import org.apache.harmony.security.x509.GeneralNames;
44import org.apache.harmony.security.x509.NameConstraints;
45import org.apache.harmony.security.x509.ORAddress;
46import org.apache.harmony.security.x509.OtherName;
47import org.apache.harmony.security.x509.SubjectPublicKeyInfo;
48import org.apache.harmony.security.x509.TBSCertificate;
49import org.apache.harmony.security.x509.Validity;
50
51/**
52 * Testing the encoding/decoding work of the following structure:
53 * (as specified in RFC 3280 -
54 *  Internet X.509 Public Key Infrastructure.
55 *  Certificate and Certificate Revocation List (CRL) Profile.
56 *  http://www.ietf.org/rfc/rfc3280.txt):
57 *
58 * <pre>
59 *   Certificate  ::=  SEQUENCE  {
60 *        tbsCertificate       TBSCertificate,
61 *        signatureAlgorithm   AlgorithmIdentifier,
62 *        signatureValue       BIT STRING
63 *   }
64 *
65 *   TBSCertificate  ::=  SEQUENCE  {
66 *        version         [0]  EXPLICIT Version DEFAULT v1,
67 *        serialNumber         CertificateSerialNumber,
68 *        signature            AlgorithmIdentifier,
69 *        issuer               Name,
70 *        validity             Validity,
71 *        subject              Name,
72 *        subjectPublicKeyInfo SubjectPublicKeyInfo,
73 *        issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
74 *                             -- If present, version MUST be v2 or v3
75 *        subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
76 *                             -- If present, version MUST be v2 or v3
77 *        extensions      [3]  EXPLICIT Extensions OPTIONAL
78 *                             -- If present, version MUST be v3
79 *   }
80 *
81 *   Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
82 *
83 *   CertificateSerialNumber  ::=  INTEGER
84 *
85 *   Validity ::= SEQUENCE {
86 *        notBefore      Time,
87 *        notAfter       Time
88 *   }
89 *
90 *   Time ::= CHOICE {
91 *        utcTime        UTCTime,
92 *        generalTime    GeneralizedTime
93 *   }
94 *
95 *   UniqueIdentifier  ::=  BIT STRING
96 *
97 *   SubjectPublicKeyInfo  ::=  SEQUENCE  {
98 *        algorithm            AlgorithmIdentifier,
99 *        subjectPublicKey     BIT STRING
100 *   }
101 *
102 *   Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
103 *
104 *   Extension  ::=  SEQUENCE  {
105 *        extnID      OBJECT IDENTIFIER,
106 *        critical    BOOLEAN DEFAULT FALSE,
107 *        extnValue   OCTET STRING
108 *   }
109 * </pre>
110 */
111
112public class CertificateTest extends TestCase {
113
114    /**
115     * Certificate(TBSCertificate tbsCertificate, AlgorithmIdentifier
116     * signatureAlgorithm, byte[] signatureValue) method testing.
117     * Makes the certificate, gets its encoded form, makes new certificate
118     * from this encoded form by CertificateFactory, and decodes encoded
119     * form.
120     */
121    public void testCertificate() throws Exception {
122        // make the TBSCertificate for Certificate
123        int version = 2; //v3
124        BigInteger serialNumber = BigInteger.valueOf(555L);
125        AlgorithmIdentifier signature = new AlgorithmIdentifier("1.2.3.44.555"); // random value
126        Name issuer = new Name("O=Certificate Issuer");
127        Validity validity = new Validity(new Date(100000000), new Date(200000000));
128        Name subject = new Name("O=Subject Organization");
129        SubjectPublicKeyInfo subjectPublicKeyInfo =
130            new SubjectPublicKeyInfo(new AlgorithmIdentifier("1.2.840.113549.1.1.2"),
131                    new byte[10]);
132        boolean[]   issuerUniqueID  = new boolean[]
133                    {true, false, true, false, true, false, true, false}; // random value
134        boolean[]   subjectUniqueID = new boolean[]
135                    {false, true, false, true, false, true, false, true}; // random value
136        // make the Extensions for TBSCertificate
137        // Subject Alternative Names
138        GeneralName[] san = new GeneralName[] {
139            new GeneralName(
140                new OtherName("1.2.3.4.5",
141                        ASN1Integer.getInstance().encode(
142                                BigInteger.valueOf(55L).toByteArray()))),
143            new GeneralName(1, "rfc@822.Name"),
144            new GeneralName(2, "dNSName"),
145            new GeneralName(new ORAddress()),
146            new GeneralName(4, "O=Organization"),
147            new GeneralName(new EDIPartyName("assigner","party")),
148            new GeneralName(6, "http://Resource.Id"),
149            new GeneralName(new byte[] {1, 1, 1, 1}),
150            new GeneralName(8, "1.2.3.4444.55555")
151        };
152        GeneralNames sans = new GeneralNames(Arrays.asList(san));
153        Extension extension = new Extension("2.5.29.17", true, sans.getEncoded());
154        Extensions extensions = new Extensions();
155        extensions.addExtension(extension);
156
157        byte[] encoding = extensions.getEncoded();
158        Extensions.ASN1.decode(encoding);
159
160        TBSCertificate tbsCertificate = new TBSCertificate(version, serialNumber,
161                signature, issuer, validity, subject, subjectPublicKeyInfo,
162                issuerUniqueID, subjectUniqueID, extensions);
163
164        encoding = tbsCertificate.getEncoded();
165        TBSCertificate.ASN1.decode(encoding);
166
167        Certificate certificate = new Certificate(tbsCertificate, signature, new byte[10]);
168
169        encoding = certificate.getEncoded();
170
171        Certificate.ASN1.decode(encoding);
172
173        encoding = Certificate.ASN1.encode(certificate);
174
175        ByteArrayInputStream bais = new ByteArrayInputStream(encoding);
176
177        //try {
178            CertificateFactory cf = CertificateFactory.getInstance("X.509");
179            cf.generateCertificate(bais);
180        //} catch (CertificateException e) {
181            // there is no X.509 certificate factory implementation installed
182        //}
183    }
184
185    /**
186     * getTbsCertificate() method testing.
187     */
188    public void testGetTbsCertificate() throws IOException {
189        // manually derived data:
190        byte[] encoding = new byte[] {
191            (byte)0x30,(byte)0x13, // NameConstraints
192                (byte)0xa1,(byte)0x11, // GeneralSubtrees (excludedSubtrees)
193                    (byte)0x30,(byte)0x0f, // GeneralSubtree
194                        (byte)0xa0,(byte)0x0a, // GeneralName
195                            // OtherName:
196                            (byte)0x06,(byte)0x03, // type-id (OID)
197                                (byte)0x00,(byte)0x01,(byte)0x02, // oid
198                            (byte)0xA0,(byte)0x03, // value (raw)
199                                1, 1, (byte)0xff,  // boolean
200                        (byte)0x80, (byte)0x01, (byte)0x00 // minimum
201        };
202        NameConstraints.ASN1.decode(encoding);
203    }
204
205    /**
206     * getSignatureAlgorithm() method testing.
207     */
208    public void testGetSignatureAlgorithm() {
209    }
210
211    /**
212     * getSignatureValue() method testing.
213     */
214    public void testGetSignatureValue() {
215    }
216
217    /**
218     * getValue() method testing.
219     */
220    public void testGetValue() {
221    }
222
223    public static Test suite() {
224        return new TestSuite(CertificateTest.class);
225    }
226
227    public static void main(String[] args) {
228        junit.textui.TestRunner.run(suite());
229    }
230}
231
232