CertificateFactory_ImplTest.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.java.security.cert;
23
24import java.io.ByteArrayInputStream;
25import java.security.KeyFactory;
26import java.security.NoSuchAlgorithmException;
27import java.security.PublicKey;
28import java.security.cert.CertPath;
29import java.security.cert.CertificateFactory;
30import java.security.cert.X509CRL;
31import java.security.cert.X509Certificate;
32import java.security.spec.X509EncodedKeySpec;
33import java.util.Collection;
34import java.util.Iterator;
35import java.util.List;
36import org.apache.harmony.luni.util.Base64;
37
38import junit.framework.TestCase;
39
40/**
41 * X.509 CertificateFactory provider implementation test.<br>
42 * See RFC 3280 (http://www.ietf.org/rfc/rfc3280.txt) for
43 * more information on X.509, and
44 * http://www.ietf.org/rfc/rfc2315.txt
45 * for more information on PKCS #7.
46 * The testing data was generated by use of classes from
47 * org.apache.harmony.security.x509 package.
48 */
49public class CertificateFactory_ImplTest extends TestCase {
50
51    /**
52     * Base64 encoded PKCS7 SignedObject containing two X.509
53     * Certificates and CRLs.
54     */
55    private static String pkcs7so =
56          "MIIHDwYJKoZIhvcNAQcCoIIHADCCBvwCAQExADALBgkqhkiG9w0BBwGg"
57        + "ggUuMIICkzCCAlOgAwIBAgICAiswCQYHKoZIzjgEAzAdMRswGQYDVQQK"
58        + "ExJDZXJ0aWZpY2F0ZSBJc3N1ZXIwIxcNMDYwOTA1MDk1MzA2WhgSMjMz"
59        + "NjEwMTMwMjUxMjcuODFaMB0xGzAZBgNVBAoTEkNlcnRpZmljYXRlIElz"
60        + "c3VlcjCCAbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu"
61        + "7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeB"
62        + "O4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD"
63        + "9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvM"
64        + "spK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlX"
65        + "TAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqL"
66        + "VHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4Vrl"
67        + "nwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDyCA7AK6Kep2soxt8tIsWW"
68        + "kafbYdueAkeBNnm46H0OteFa80HMuJjKJ0LjlPrdjFMARKyW/GATtQhg"
69        + "hY/MrINAHmKcX5QjL1DkuJKDNggLHqj5D6efsWmLKwLvmviWLzWtjh7Y"
70        + "GBZeLt0ezu2q49aKcOzkkDsCSsMz09u9284L6qMeMBwwGgYDVR0RAQH/"
71        + "BBAwDoEMcmZjQDgyMi5OYW1lMAkGByqGSM44BAMDLwAwLAIUWo0C+R8P"
72        + "J8LGSLsCRqJ8SOOO0SoCFGvO6mpNdzOKiwlYwfpF/Xyi7s3vMIICkzCC"
73        + "AlOgAwIBAgICAiswCQYHKoZIzjgEAzAdMRswGQYDVQQKExJDZXJ0aWZp"
74        + "Y2F0ZSBJc3N1ZXIwIxcNMDYwOTA1MDk1MzA2WhgSMjMzNjEwMTMwMjUx"
75        + "MjcuODFaMB0xGzAZBgNVBAoTEkNlcnRpZmljYXRlIElzc3VlcjCCAbgw"
76        + "ggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3Ujzv"
77        + "RADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3"
78        + "a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQT"
79        + "WhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvw"
80        + "WBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlX"
81        + "jrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4r"
82        + "s6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtV"
83        + "JWQBTDv+z0kqA4GFAAKBgQDyCA7AK6Kep2soxt8tIsWWkafbYdueAkeB"
84        + "Nnm46H0OteFa80HMuJjKJ0LjlPrdjFMARKyW/GATtQhghY/MrINAHmKc"
85        + "X5QjL1DkuJKDNggLHqj5D6efsWmLKwLvmviWLzWtjh7YGBZeLt0ezu2q"
86        + "49aKcOzkkDsCSsMz09u9284L6qMeMBwwGgYDVR0RAQH/BBAwDoEMcmZj"
87        + "QDgyMi5OYW1lMAkGByqGSM44BAMDLwAwLAIUWo0C+R8PJ8LGSLsCRqJ8"
88        + "SOOO0SoCFGvO6mpNdzOKiwlYwfpF/Xyi7s3voYIBsjCB1jCBlwIBATAJ"
89        + "BgcqhkjOOAQDMBUxEzARBgNVBAoTCkNSTCBJc3N1ZXIXDTA2MDkwNTA5"
90        + "NTMwN1oXDTA2MDkwNTA5NTQ0N1owQTA/AgICKxcNMDYwOTA1MDk1MzA4"
91        + "WjAqMAoGA1UdFQQDCgEBMBwGA1UdGAQVGBMyMDA2MDkwNTA5NTMwNy43"
92        + "MThaoA8wDTALBgNVHRQEBAICEVwwCQYHKoZIzjgEAwMvADAsAhR/l5kI"
93        + "bTkuJe9HjcpZ4Ff4Ifv9xwIUIXBlDKsNFlgYdWWTxzrrJOHyMuUwgdYw"
94        + "gZcCAQEwCQYHKoZIzjgEAzAVMRMwEQYDVQQKEwpDUkwgSXNzdWVyFw0w"
95        + "NjA5MDUwOTUzMDdaFw0wNjA5MDUwOTU0NDdaMEEwPwICAisXDTA2MDkw"
96        + "NTA5NTMwOFowKjAKBgNVHRUEAwoBATAcBgNVHRgEFRgTMjAwNjA5MDUw"
97        + "OTUzMDcuNzE4WqAPMA0wCwYDVR0UBAQCAhFcMAkGByqGSM44BAMDLwAw"
98        + "LAIUf5eZCG05LiXvR43KWeBX+CH7/ccCFCFwZQyrDRZYGHVlk8c66yTh"
99        + "8jLlMQA=";
100
101    /**
102     * Base64 encoded PkiPath object containing 2 X.509 certificates.
103     */
104    private static String pkiPath =
105          "MIIFMDCCApQwggJToAMCAQICAgIrMAkGByqGSM44BAMwHTEbMBkGA1UE"
106        + "ChMSQ2VydGlmaWNhdGUgSXNzdWVyMCMXDTA2MDkwNTExMDAyM1oYEjIz"
107        + "MzYxMDEzMTQwNDE4LjEyWjAdMRswGQYDVQQKExJDZXJ0aWZpY2F0ZSBJ"
108        + "c3N1ZXIwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEA/X9TgR11EilS30qc"
109        + "Luzk5/YRt1I870QAwx4/gLZRJmlFXUAiUftZPY1Y+r/F9bow9subVWzX"
110        + "gTuAHTRv8mZgt2uZUKWkn5/oBHsQIsJPu6nX/rfGG/g7V+fGqKYVDwT7"
111        + "g/bTxR7DAjVUE1oWkTL2dfOuK2HXKu/yIgMZndFIAccCFQCXYFCPFSML"
112        + "zLKSuYKi64QL8Fgc9QKBgQD34aCF1ps93su8q1w2uFe5eZSvu/o66oL5"
113        + "V0wLPQeCZ1FZV4661FlP5nEHEIGAtEkWcSPoTCgWE7fPCTKMyKbhPBZ6"
114        + "i1R8jSjgo64eK7OmdZFuo38L+iE1YvH7YnoBJDvMpPG+qFGQiaiD3+Fa"
115        + "5Z8GkotmXoB7VSVkAUw7/s9JKgOBhQACgYEA8ggOwCuinqdrKMbfLSLF"
116        + "lpGn22HbngJHgTZ5uOh9DrXhWvNBzLiYyidC45T63YxTAESslvxgE7UI"
117        + "YIWPzKyDQB5inF+UIy9Q5LiSgzYICx6o+Q+nn7FpiysC75r4li81rY4e"
118        + "2BgWXi7dHs7tquPWinDs5JA7AkrDM9PbvdvOC+qjHjAcMBoGA1UdEQEB"
119        + "/wQQMA6BDHJmY0A4MjIuTmFtZTAJBgcqhkjOOAQDAzAAMC0CFQCAUA72"
120        + "3BIXNluugYcScXeb9vx5vAIUYreCA5ljANvzSsD0ofI+xph4//IwggKU"
121        + "MIICU6ADAgECAgICKzAJBgcqhkjOOAQDMB0xGzAZBgNVBAoTEkNlcnRp"
122        + "ZmljYXRlIElzc3VlcjAjFw0wNjA5MDUxMTAwMjNaGBIyMzM2MTAxMzE0"
123        + "MDQxOC4xMlowHTEbMBkGA1UEChMSQ2VydGlmaWNhdGUgSXNzdWVyMIIB"
124        + "uDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdS"
125        + "PO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/Jm"
126        + "YLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1"
127        + "VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuE"
128        + "C/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdR"
129        + "WVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOu"
130        + "HiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6A"
131        + "e1UlZAFMO/7PSSoDgYUAAoGBAPIIDsArop6nayjG3y0ixZaRp9th254C"
132        + "R4E2ebjofQ614VrzQcy4mMonQuOU+t2MUwBErJb8YBO1CGCFj8ysg0Ae"
133        + "YpxflCMvUOS4koM2CAseqPkPp5+xaYsrAu+a+JYvNa2OHtgYFl4u3R7O"
134        + "7arj1opw7OSQOwJKwzPT273bzgvqox4wHDAaBgNVHREBAf8EEDAOgQxy"
135        + "ZmNAODIyLk5hbWUwCQYHKoZIzjgEAwMwADAtAhUAgFAO9twSFzZbroGH"
136        + "EnF3m/b8ebwCFGK3ggOZYwDb80rA9KHyPsaYeP/y";
137
138    /**
139     * Base64 encoded X.509 CRL.
140     */
141    private static String x509crl =
142          "MIHWMIGWAgEBMAkGByqGSM44BAMwFTETMBEGA1UEChMKQ1JMIElzc3Vl"
143        + "chcNMDYwOTA1MDk1MzA4WhcNMDYwOTA1MDk1NDQ4WjBAMD4CAgIrFw0w"
144        + "NjA5MDUwOTUzMDhaMCkwCgYDVR0VBAMKAQEwGwYDVR0YBBQYEjIwMDYw"
145        + "OTA1MDk1MzA4Ljg5WqAPMA0wCwYDVR0UBAQCAhFcMAkGByqGSM44BAMD"
146        + "MAAwLQIUJ1KAJumw8mOpGXT/FS5K9WwOBRICFQCR+ez59x9GH3sKoByC"
147        + "IooeR20Q3Q==";
148
149    /**
150     * Base64 encoded X.509 Certificate.
151     */
152    private static String x509cert =
153          "MIICkzCCAlOgAwIBAgICAiswCQYHKoZIzjgEAzAdMRswGQYDVQQKExJD"
154        + "ZXJ0aWZpY2F0ZSBJc3N1ZXIwIxcNMDYwOTA4MDU1NzUxWhgSMjMzNjEx"
155        + "MTAxMTM4NTUuNjJaMB0xGzAZBgNVBAoTEkNlcnRpZmljYXRlIElzc3Vl"
156        + "cjCCAbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn"
157        + "9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4Ad"
158        + "NG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPF"
159        + "HsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5"
160        + "gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9"
161        + "B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyN"
162        + "KOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaS"
163        + "i2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDyCA7AK6Kep2soxt8tIsWWkafb"
164        + "YdueAkeBNnm46H0OteFa80HMuJjKJ0LjlPrdjFMARKyW/GATtQhghY/M"
165        + "rINAHmKcX5QjL1DkuJKDNggLHqj5D6efsWmLKwLvmviWLzWtjh7YGBZe"
166        + "Lt0ezu2q49aKcOzkkDsCSsMz09u9284L6qMeMBwwGgYDVR0RAQH/BBAw"
167        + "DoEMcmZjQDgyMi5OYW1lMAkGByqGSM44BAMDLwAwLAIUO+JWKWai/8Si"
168        + "2oEfhKSobLttYeYCFFO5YVDvtnmVVnvQTtUvrPpsaxJR";
169
170    /**
171     * Base64 encoded Private Key used for data signing.
172     * This data is not directly used in the test, but it could be
173     * useful in future in case of implementation of additional
174     * testing data structures.
175     */
176    private static String b64PrivateKeySpec =
177          "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s"
178        + "5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7"
179        + "gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P2"
180        + "08UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yy"
181        + "krmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdM"
182        + "Cz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotU"
183        + "fI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWf"
184        + "BpKLZl6Ae1UlZAFMO/7PSSoEFgIUS24w346zv1ic3wsLOHzxQnf9aX0=";
185
186    /**
187     * Base64 encoded Public Key for signature verification.
188     */
189    private static String b64PublicKeySpec =
190          "MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2"
191        + "EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00"
192        + "b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208Ue"
193        + "wwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmC"
194        + "ouuEC/BYHPUCgYEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0H"
195        + "gmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o"
196        + "4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKL"
197        + "Zl6Ae1UlZAFMO/7PSSoDgYUAAoGBAPIIDsArop6nayjG3y0ixZaRp9th"
198        + "254CR4E2ebjofQ614VrzQcy4mMonQuOU+t2MUwBErJb8YBO1CGCFj8ys"
199        + "g0AeYpxflCMvUOS4koM2CAseqPkPp5+xaYsrAu+a+JYvNa2OHtgYFl4u"
200        + "3R7O7arj1opw7OSQOwJKwzPT273bzgvq";
201
202    /**
203     * The name of the algorithm used for Certificate/CRL signing.
204     */
205    private static String publicKeyAlgorithm = "DSA";
206
207    /**
208     * The public key to verify generated Certificates and CRLs.
209     */
210    private static PublicKey publicKey;
211
212    static {
213        try {
214            X509EncodedKeySpec publicKeySpec =
215                new X509EncodedKeySpec(
216                        Base64.decode(b64PublicKeySpec.getBytes("UTF-8")));
217            KeyFactory keyFactory =
218                KeyFactory.getInstance(publicKeyAlgorithm);
219            publicKey = keyFactory.generatePublic(publicKeySpec);
220        } catch (NoSuchAlgorithmException e) {
221            // provider is not installed, will not verify the generated data
222            publicKey = null;
223        } catch (Exception e) {
224            // problems with a representation of the key
225            e.printStackTrace();
226            publicKey = null;
227        }
228    }
229
230    // array contains allowed PEM delimiters
231    private static String[][] good = {
232        {"-----BEGIN\n", "\n-----END"},
233        {"-----BEGIN-----\n", "\n-----END-----"},
234        {"-----BEGIN PEM ENCODED DATA STRUCTURE-----\n", "\n-----END-----"},
235        {"-----BEGIN MEANINGLESS SEPARATOR\n", "\n-----END PEM"},
236    };
237
238    // array contains not allowed PEM delimiters
239    private static String[][] bad = {
240        {"----BEGI\n", "\n-----END"},
241        {"-----BEGI\n", "\n----END"},
242        {"-----BEGI\n", "\n-----END"},
243        {"-----BEGIN\n", "\n-----EN"},
244        {"-----BEGIN", "\n-----END"},
245        {"-----BEGIN\n", "-----END"},
246    };
247
248    // array contains bad PEM encoded content.
249    private static String[] bad_content = {
250        "MIIHDwYJ", "ABCD", "\r\n\r\n", "\n\r", ""
251    };
252
253    /**
254     * generateCRLs method testing.
255     * Generates CRLs on the base of PKCS7 SignedData Object
256     */
257    public void testGenerateCRLs() throws Exception {
258        CertificateFactory factory = CertificateFactory.getInstance("X.509");
259
260        // Testing the CRLs generation on the base of PKCS7 SignedData object
261        ByteArrayInputStream bais = new ByteArrayInputStream(
262                Base64.decode(pkcs7so.getBytes("UTF-8")));
263
264        Collection crls = factory.generateCRLs(bais);
265        assertNotNull("Factory returned null on correct PKCS7 data", crls);
266        assertEquals("The size of collection differs from expected",
267                2, crls.size());
268
269        if (publicKey != null) {
270            // verify the signatures
271            for (Iterator i = crls.iterator(); i.hasNext();) {
272                ((X509CRL) i.next()).verify(publicKey);
273            }
274        }
275    }
276
277    /**
278     * generateCRL/generateCertificate method testing.
279     * Tries to generates single CRL/Certificate
280     * on the base of PKCS7 SignedData Object.
281     */
282    public void testGenerateCRL() throws Exception {
283        CertificateFactory factory = CertificateFactory.getInstance("X.509");
284
285        ByteArrayInputStream bais = new ByteArrayInputStream(
286                Base64.decode(pkcs7so.getBytes("UTF-8")));
287        try {
288            factory.generateCRL(bais);
289            fail("Expected exception was not thrown");
290        } catch (Exception e) { }
291        bais = new ByteArrayInputStream(Base64.decode(pkcs7so.getBytes("UTF-8")));
292        try {
293            factory.generateCertificate(bais);
294            fail("Expected exception was not thrown");
295        } catch (Exception e) { }
296    }
297
298    /**
299     * Generates CRLs on the base of PEM encoding.
300     */
301    public void testGenerateBase64CRL() throws Exception {
302        CertificateFactory factory = CertificateFactory.getInstance("X.509");
303        ByteArrayInputStream bais;
304
305        for (int i=0; i<good.length; i++) {
306            bais = new ByteArrayInputStream(
307                    (good[i][0] + x509crl + good[i][1]).getBytes("UTF-8"));
308
309            X509CRL crl = (X509CRL) factory.generateCRL(bais);
310            assertNotNull("Factory returned null on correct data", crl);
311
312            if (publicKey != null) {
313                // verify the signatures
314                crl.verify(publicKey);
315            }
316        }
317
318        for (int i=0; i<bad_content.length; i++) {
319            bais = new ByteArrayInputStream(
320                    (good[0][0] + bad_content[i] + good[0][1]).getBytes("UTF-8"));
321            try {
322                factory.generateCRL(bais);
323                fail("Expected exception was not thrown");
324            } catch (Exception e) {
325                // e.printStackTrace();
326            }
327        }
328
329        for (int i=0; i<bad.length; i++) {
330            bais = new ByteArrayInputStream(
331                    (bad[i][0] + x509crl + bad[i][1]).getBytes("UTF-8"));
332            try {
333                factory.generateCRL(bais);
334                fail("Expected exception was not thrown");
335            } catch (Exception e) { }
336        }
337    }
338
339    private void verifyCRLs(Collection crls) throws Exception {
340        if (publicKey != null) {
341            // verify the signatures
342            for (Iterator it = crls.iterator(); it.hasNext();) {
343                ((X509CRL) it.next()).verify(publicKey);
344            }
345        }
346    };
347
348    private void verifyCertificates(Collection certs) throws Exception {
349        if (publicKey != null) {
350            // verify the signatures
351            for (Iterator it = certs.iterator(); it.hasNext();) {
352                ((X509Certificate) it.next()).verify(publicKey);
353            }
354        }
355    };
356
357    /**
358     * generateCRLs method testing.
359     * Generates CRLs on the base of consequent
360     * PEM X.509(ASN.1)/X.509(ASN.1)/PKCS7 forms.
361     */
362    public void testGenerateBase64CRLs() throws Exception {
363        CertificateFactory factory = CertificateFactory.getInstance("X.509");
364
365        // ------------------------ Test Data -----------------------------
366        // encoding describing codes
367        int pem_x509 = 0, asn_x509 = 1, pem_pkcs = 2, asn_pkcs = 3,
368            bad = 4, npe_bad = 5, npe_bad2 = 6, num_of_variants = 7;
369        // error code, marks sequences as throwing exceptions
370        int error = 999;
371        // test sequences
372        int[][] sequences = {
373            {pem_x509, pem_x509},
374            {pem_x509, asn_x509},
375            {pem_x509, asn_x509, pem_x509},
376            {asn_x509, asn_x509},
377            {asn_x509, pem_x509},
378            {asn_x509, pem_x509, asn_x509},
379            // -1 means that only 1 (-(-1)) CRL will be generated
380            // on the base of this encodings sequence
381            {-1, pem_x509, pem_pkcs},
382            {-1, pem_x509, bad},
383            // {-1/*-error*/, pem_x509, npe_bad2},
384            // {-1/*-error*/, pem_x509, npe_bad},
385            {-2, pem_pkcs, pem_x509}, // 2 CRLs are expected
386            {-2, pem_pkcs, bad},
387            {-2, pem_pkcs, npe_bad},
388            {-2, pem_pkcs, npe_bad2},
389            {-1, asn_x509, pem_pkcs},
390            {-1, asn_x509, bad},
391            // {-1/*-error*/, asn_x509, npe_bad},
392            // {-1/*-error*/, asn_x509, npe_bad2},
393            // exception is expected
394            {-error, bad},
395            {-error, bad, asn_x509},
396            {-error, npe_bad},
397            {-error, npe_bad2},
398        };
399        // actual encodings
400        byte[][] data = new byte[num_of_variants][];
401        data[pem_x509] = (good[0][0] + x509crl + good[0][1] + "\n").getBytes("UTF-8");
402        data[asn_x509] = Base64.decode(x509crl.getBytes("UTF-8"));
403        data[pem_pkcs] = (good[0][0] + pkcs7so + good[0][1] + "\n").getBytes("UTF-8");
404        data[asn_pkcs] = Base64.decode(pkcs7so.getBytes("UTF-8"));
405        data[bad] = new byte[] {0, 1, 1, 1, 1, 1, 0, 1};
406        data[npe_bad] = new byte[] {0, 1, 1, 1, 1, 1, 1, 0};
407        data[npe_bad2] = new byte[] {48, 0, 3, 4, 5, 6, 7};
408
409        // -------------------------- Test --------------------------------
410        // Tests CRL generation on the base of sequences of heterogeneous
411        // data format
412        for (int i=0; i<sequences.length; i++) { // for each of the sequences..
413            // expected size og generated CRL collection
414            int expected_size = (sequences[i][0] < 0)
415                ? -sequences[i][0]
416                : sequences[i].length;
417            // compute the size of the encoding described by sequence
418            int encoding_size = 0;
419            //System.out.print("Sequence:");
420            for (int j=0; j<sequences[i].length; j++) {
421                //System.out.print(" "+sequences[i][j]);
422                if (sequences[i][j] >= 0) {
423                    encoding_size += data[sequences[i][j]].length;
424                }
425            }
426            //System.out.println("");
427            // create the encoding of described sequence
428            byte[] encoding = new byte[encoding_size];
429            int position = 0;
430            for (int j=0; j<sequences[i].length; j++) {
431                if (sequences[i][j] >= 0) {
432                    System.arraycopy(
433                            data[sequences[i][j]], 0, // from
434                            encoding, position, // to
435                            data[sequences[i][j]].length); // length
436                    position += data[sequences[i][j]].length;
437                }
438            }
439
440            if (expected_size == error) { // exception throwing test
441                try {
442                    factory.generateCRLs(new ByteArrayInputStream(encoding));
443                    fail("Expected exception was not thrown");
444                } catch (Exception e) { }
445            } else {
446                Collection crls =
447                    factory.generateCRLs(new ByteArrayInputStream(encoding));
448                assertNotNull("Factory returned null on correct data", crls);
449                assertEquals("The size of collection differs from expected",
450                        expected_size, crls.size());
451                verifyCRLs(crls);
452            }
453        }
454    }
455
456    /**
457     * generateCertificates method testing.
458     * Generates Certificates on the base of consequent
459     * PEM X.509(ASN.1)/X.509(ASN.1)/PKCS7 forms.
460     */
461    public void testGenerateBase64Certificates() throws Exception {
462        CertificateFactory factory = CertificateFactory.getInstance("X.509");
463
464        // ------------------------ Test Data -----------------------------
465        // encoding describing codes
466        int pem_x509 = 0, asn_x509 = 1, pem_pkcs = 2, asn_pkcs = 3,
467            bad = 4, bad1 = 5, bad2 = 6, num_of_variants = 7;
468        // error code, marks sequences as throwing exceptions
469        int error = 999;
470        // test sequences
471        int[][] sequences = {
472            {pem_x509, pem_x509},
473            {pem_x509, asn_x509},
474            {pem_x509, asn_x509, pem_x509},
475            {asn_x509, asn_x509},
476            {asn_x509, pem_x509},
477            {asn_x509, pem_x509, asn_x509},
478            // -1 means that only 1 (-(-1)) Certificate will be generated
479            // on the base of this encodings sequence
480            // {-1/*-error*/, pem_x509, pem_pkcs},
481            // {-1/*-error*/, pem_x509, bad},
482            {-2, pem_pkcs, pem_x509}, // 2 Certificates are expected
483            {-2, pem_pkcs, bad},
484            {-2, pem_pkcs, bad1},
485            {-2, pem_pkcs, bad2},
486            // {-1/*-error*/, asn_x509, pem_pkcs},
487            // {-1/*-error*/, asn_x509, bad},
488            // {-1/*-error*/, asn_x509, bad1},
489            // {-1/*-error*/, pem_x509, bad1},
490            // {-1/*-error*/, asn_x509, bad2},
491            // {-1/*-error*/, pem_x509, bad2},
492            // exception is expected
493            {-error, bad},
494            {-error, bad, asn_x509},
495            {-error, bad1},
496            {-error, bad2},
497        };
498        // actual encodings
499        byte[][] data = new byte[num_of_variants][];
500        data[pem_x509] = (good[0][0] + x509cert + good[0][1] + "\n").getBytes("UTF-8");
501        data[asn_x509] = Base64.decode(x509cert.getBytes("UTF-8"));
502        data[pem_pkcs] = (good[0][0] + pkcs7so + good[0][1] + "\n").getBytes("UTF-8");
503        data[asn_pkcs] = Base64.decode(pkcs7so.getBytes("UTF-8"));
504        data[bad] = new byte[] {0, 1, 1, 1, 1, 1, 0, 1};
505        data[bad1] = new byte[] {0, 1, 1, 1, 1, 1, 1, 0};
506        data[bad2] = new byte[] {48, 0, 3, 4, 5, 6, 7};
507
508        // -------------------------- Test --------------------------------
509        // Tests Certificate generation on the base of sequences of heterogeneous
510        // data format
511        for (int i=0; i<sequences.length; i++) { // for each of the sequences..
512            // expected size og generated Certificate collection
513            int expected_size = (sequences[i][0] < 0)
514                ? -sequences[i][0]
515                : sequences[i].length;
516            // compute the size of the encoding described by sequence
517            int encoding_size = 0;
518            //System.out.print("Sequence:");
519            for (int j=0; j<sequences[i].length; j++) {
520                //System.out.print(" "+sequences[i][j]);
521                if (sequences[i][j] >= 0) {
522                    encoding_size += data[sequences[i][j]].length;
523                }
524            }
525            //System.out.println("");
526            // create the encoding of described sequence
527            byte[] encoding = new byte[encoding_size];
528            int position = 0;
529            for (int j=0; j<sequences[i].length; j++) {
530                if (sequences[i][j] >= 0) {
531                    System.arraycopy(
532                            data[sequences[i][j]], 0, // from
533                            encoding, position, // to
534                            data[sequences[i][j]].length); // length
535                    position += data[sequences[i][j]].length;
536                }
537            }
538
539            if (expected_size == error) { // exception throwing test
540                try {
541                    factory.generateCertificates(new ByteArrayInputStream(encoding));
542                    fail("Expected exception was not thrown");
543                } catch (Exception e) { }
544            } else {
545                Collection certs =
546                    factory.generateCertificates(new ByteArrayInputStream(encoding));
547                assertNotNull("Factory returned null on correct data", certs);
548                assertEquals("The size of collection differs from expected",
549                        expected_size, certs.size());
550                verifyCertificates(certs);
551            }
552        }
553    }
554
555    /**
556     * Generates CRLs/Certificates on the base of PEM PKCS7 encoding.
557     */
558    public void testGenerateBase64PKCS7() throws Exception {
559        CertificateFactory factory = CertificateFactory.getInstance("X.509");
560
561        ByteArrayInputStream bais;
562        for (int i=0; i<good.length; i++) {
563            bais = new ByteArrayInputStream(
564                    (good[i][0] + pkcs7so + good[i][1]).getBytes("UTF-8"));
565            Collection crls = factory.generateCRLs(bais);
566            assertNotNull("Factory returned null on correct PKCS7 data", crls);
567            assertEquals("The size of collection differs from expected",
568                    2, crls.size());
569            if (publicKey != null) {
570                // verify the signatures
571                for (Iterator it = crls.iterator(); it.hasNext();) {
572                    ((X509CRL) it.next()).verify(publicKey);
573                }
574            }
575            bais = new ByteArrayInputStream(
576                    (good[i][0] + pkcs7so + good[i][1]).getBytes("UTF-8"));
577            Collection certs = factory.generateCertificates(bais);
578            assertNotNull("Factory returned null on correct PKCS7 data", certs);
579            assertEquals("The size of collection differs from expected",
580                    2, certs.size());
581            if (publicKey != null) {
582                // verify the signatures
583                for (Iterator it = certs.iterator(); it.hasNext();) {
584                    ((X509Certificate) it.next()).verify(publicKey);
585                }
586            }
587        }
588
589        for (int i=0; i<bad_content.length; i++) {
590            bais = new ByteArrayInputStream(
591                    (good[0][0] + bad_content[i] + good[0][1]).getBytes("UTF-8"));
592            try {
593                factory.generateCertificates(bais);
594                fail("Expected exception was not thrown");
595            } catch (Exception e) { }
596            bais = new ByteArrayInputStream(
597                    (good[0][0] + bad_content[i] + good[0][1]).getBytes("UTF-8"));
598            try {
599                factory.generateCRLs(bais);
600                fail("Expected exception was not thrown");
601            } catch (Exception e) { }
602        }
603
604        for (int i=0; i<bad.length; i++) {
605            bais = new ByteArrayInputStream(
606                    (bad[i][0] + pkcs7so + bad[i][1]).getBytes("UTF-8"));
607            try {
608                factory.generateCRLs(bais);
609                fail("Expected exception was not thrown");
610            } catch (Exception e) { }
611            bais = new ByteArrayInputStream(
612                    (bad[i][0] + pkcs7so + bad[i][1]).getBytes("UTF-8"));
613            try {
614                factory.generateCertificates(bais);
615                fail("Expected exception was not thrown");
616            } catch (Exception e) { }
617        }
618    }
619
620    /**
621     * Generates CertPaths on the base of PEM PkiPath/PKCS7 encoding.
622     */
623    public void testGenerateBase64CertPath() throws Exception {
624        CertificateFactory factory = CertificateFactory.getInstance("X.509");
625
626        ByteArrayInputStream bais;
627        List certificates;
628        for (int i=0; i<good.length; i++) {
629            bais = new ByteArrayInputStream(
630                    (good[i][0] + pkiPath + good[i][1]).getBytes("UTF-8"));
631
632            certificates = factory.generateCertPath(bais).getCertificates();
633            assertEquals("The size of the list differs from expected",
634                    2, certificates.size());
635
636            if (publicKey != null) {
637                // verify the signatures
638                for (Iterator it = certificates.iterator(); it.hasNext();) {
639                    ((X509Certificate) it.next()).verify(publicKey);
640                }
641            }
642
643            bais = new ByteArrayInputStream(
644                    (good[i][0] + pkiPath + good[i][1]).getBytes("UTF-8"));
645
646            certificates =
647                factory.generateCertPath(bais, "PkiPath").getCertificates();
648            assertEquals("The size of the list differs from expected",
649                    2, certificates.size());
650
651            if (publicKey != null) {
652                // verify the signatures
653                for (Iterator it = certificates.iterator(); it.hasNext();) {
654                    ((X509Certificate) it.next()).verify(publicKey);
655                }
656            }
657
658            bais = new ByteArrayInputStream(
659                    (good[i][0] + pkcs7so + good[i][1]).getBytes("UTF-8"));
660
661            certificates =
662                factory.generateCertPath(bais, "PKCS7").getCertificates();
663            assertEquals("The size of the list differs from expected",
664                    2, certificates.size());
665
666            if (publicKey != null) {
667                // verify the signatures
668                for (Iterator it = certificates.iterator(); it.hasNext();) {
669                    ((X509Certificate) it.next()).verify(publicKey);
670                }
671            }
672        }
673
674        // testing empty PkiPath structure (ASN.1 such as 0x30, 0x00)
675        bais = new ByteArrayInputStream(
676                (good[0][0] + "MAB=" + good[0][1]).getBytes("UTF-8")); // "MABCDEFG"
677        assertEquals("The size of the list differs from expected",
678                0, factory.generateCertPath(bais, "PkiPath")
679                                .getCertificates().size());
680
681        // testing with bad PEM content
682        for (int i=0; i<bad_content.length; i++) {
683            bais = new ByteArrayInputStream(
684                    (good[0][0] + bad_content[i] + good[0][1]).getBytes("UTF-8"));
685            try {
686                factory.generateCertPath(bais);
687                fail("Expected exception was not thrown");
688            } catch (Exception e) { }
689            bais = new ByteArrayInputStream(
690                    (good[0][0] + bad_content[i] + good[0][1]).getBytes("UTF-8"));
691            try {
692                factory.generateCertPath(bais, "PkiPath");
693                fail("Expected exception was not thrown");
694            } catch (Exception e) { }
695            bais = new ByteArrayInputStream(
696                    (good[0][0] + bad_content[i] + good[0][1]).getBytes("UTF-8"));
697            try {
698                factory.generateCertPath(bais, "PKCS7");
699                fail("Expected exception was not thrown");
700            } catch (Exception e) { }
701        }
702
703        for (int i=0; i<bad.length; i++) {
704            bais = new ByteArrayInputStream(
705                    (bad[i][0] + pkiPath + bad[i][1]).getBytes("UTF-8"));
706            try {
707                factory.generateCertPath(bais);
708                fail("Expected exception was not thrown");
709            } catch (Exception e) { }
710            bais = new ByteArrayInputStream(
711                    (bad[i][0] + pkiPath + bad[i][1]).getBytes("UTF-8"));
712            try {
713                factory.generateCertPath(bais, "PkiPath");
714                fail("Expected exception was not thrown");
715            } catch (Exception e) { }
716            bais = new ByteArrayInputStream(
717                    (bad[i][0] + pkcs7so + bad[i][1]).getBytes("UTF-8"));
718            try {
719                factory.generateCertPath(bais, "PKCS7");
720                fail("Expected exception was not thrown");
721            } catch (Exception e) { }
722        }
723    }
724
725    /**
726     * generateCertificates method testing.
727     */
728    public void testGenerateCertificates() throws Exception {
729        CertificateFactory factory = CertificateFactory.getInstance("X.509");
730
731        // Testing the Certificates generation
732        // on the base of PKCS7 SignedData object
733        ByteArrayInputStream bais = new ByteArrayInputStream(
734                Base64.decode(pkcs7so.getBytes("UTF-8")));
735
736        Collection certs = factory.generateCertificates(bais);
737        assertNotNull("Factory returned null on correct PKCS7 data", certs);
738        assertEquals("The size of collection differs from expected",
739                2, certs.size());
740
741        if (publicKey != null) {
742            // verify the signatures
743            for (Iterator i = certs.iterator(); i.hasNext();) {
744                ((X509Certificate) i.next()).verify(publicKey);
745            }
746        }
747    }
748
749    /**
750     * generateCertificates method testing.
751     */
752    public void testGenerateCertPath() throws Exception {
753        CertificateFactory factory = CertificateFactory.getInstance("X.509");
754
755        // Testing the CertPath generation
756        // on the base of PKCS7 SignedData object
757        ByteArrayInputStream bais = new ByteArrayInputStream(
758                Base64.decode(pkcs7so.getBytes("UTF-8")));
759
760        Collection certPath =
761            factory.generateCertPath(bais, "PKCS7").getCertificates();
762        assertEquals("The size of collection differs from expected",
763                2, certPath.size());
764
765        if (publicKey != null) {
766            // verify the signatures
767            for (Iterator i = certPath.iterator(); i.hasNext();) {
768                ((X509Certificate) i.next()).verify(publicKey);
769            }
770        }
771
772        // testing empty PkiPath structure (ASN.1 such as 0x30, 0x00)
773        bais = new ByteArrayInputStream(new byte[] {(byte) 0x30, 0x00});
774        assertEquals("The size of the list differs from expected",
775                0, factory.generateCertPath(bais, "PkiPath")
776                                .getCertificates().size());
777    }
778
779}
780