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 Vera Y. Petrashkova
20* @version $Revision$
21*/
22
23package org.apache.harmony.security.tests.java.security;
24
25import java.io.IOException;
26import java.security.KeyStore;
27import java.security.KeyStoreException;
28import java.security.Provider;
29import java.security.Security;
30import java.security.SignatureException;
31import java.security.Principal;
32import java.security.PublicKey;
33import java.security.InvalidKeyException;
34import java.security.NoSuchProviderException;
35import java.security.NoSuchAlgorithmException;
36import java.security.cert.Certificate;
37import java.security.cert.CertificateException;
38import java.security.cert.CertificateEncodingException;
39import java.security.cert.CertificateExpiredException;
40import java.security.cert.CertificateNotYetValidException;
41import java.security.cert.X509Certificate;
42import java.util.Date;
43import java.util.Set;
44import java.math.BigInteger;
45import javax.crypto.KeyGenerator;
46import javax.crypto.SecretKey;
47
48import org.apache.harmony.security.tests.support.KeyStoreTestSupport;
49import org.apache.harmony.security.tests.support.MyLoadStoreParams;
50import org.apache.harmony.security.tests.support.SpiEngUtils;
51
52import junit.framework.TestCase;
53
54/**
55 * Tests for <code>KeyStore</code> constructor and methods
56 *
57 */
58public class KeyStoreTest extends TestCase {
59
60    private static final String KeyStoreProviderClass = "org.apache.harmony.security.tests.support.MyKeyStore";
61
62    private static final String defaultType = "KeyStore";
63
64    public static boolean KSSupported = false;
65
66    public static String defaultProviderName = null;
67
68    public static Provider defaultProvider = null;
69
70    private static String NotSupportMsg = "Default KeyStore type is not supported";
71
72    Provider mProv;
73
74    public KeyStore[] createKS() throws Exception {
75        assertTrue(NotSupportMsg, KSSupported);
76        KeyStore[] kpg = new KeyStore[3];
77
78        kpg[0] = KeyStore.getInstance(defaultType);
79        kpg[1] = KeyStore.getInstance(defaultType, defaultProvider);
80        kpg[2] = KeyStore.getInstance(defaultType, defaultProviderName);
81        return kpg;
82    }
83
84    protected void setUp() throws Exception {
85        super.setUp();
86        mProv = (new SpiEngUtils()).new MyProvider("MyKSProvider",
87                "Testing provider", KeyStoreTestSupport.srvKeyStore.concat(".")
88                        .concat(defaultType), KeyStoreProviderClass);
89        Security.insertProviderAt(mProv, 2);
90        defaultProvider = SpiEngUtils.isSupport(defaultType,
91                KeyStoreTestSupport.srvKeyStore);
92        KSSupported = (defaultProvider != null);
93        defaultProviderName = (KSSupported ? defaultProvider.getName() : null);
94    }
95
96    /*
97     * @see TestCase#tearDown()
98     */
99    protected void tearDown() throws Exception {
100        super.tearDown();
101        Security.removeProvider(mProv.getName());
102    }
103
104    /**
105     * Test for <code>load(LoadStoreParameter param)</code>
106     * <code>store(LoadStoreParameter param)</code>
107     * methods
108     * Assertions: throw IllegalArgumentException if param is null;
109     */
110    public void testLoadStore02() throws Exception {
111        assertTrue(NotSupportMsg, KSSupported);
112
113        KeyStore[] kss = createKS();
114        assertNotNull("KeyStore objects were not created", kss);
115
116        for (int i = 0; i < kss.length; i++) {
117            try {
118                kss[i].load(null);
119                fail("IOException or IllegalArgumentException should be thrown for null parameter");
120            } catch (IOException e) {
121            } catch (IllegalArgumentException e) {
122            }
123            kss[i].load(null, null);
124            try {
125                kss[i].store(null);
126                fail("IOException or IllegalArgumentException should be thrown for null parameter");
127            } catch (IOException e) {
128            } catch (IllegalArgumentException e) {
129            }
130        }
131        KeyStore.LoadStoreParameter lParam = new MyLoadStoreParams(
132                new KeyStore.PasswordProtection(new char[0]));
133        for (int i = 0; i < kss.length; i++) {
134            kss[i].load(lParam);
135            assertEquals("Incorrect result", kss[i].size(), 0);
136            kss[i].store(lParam);
137        }
138    }
139
140
141    /**
142     * Test for <code>setKeyEntry(String alias, byte[] key, Certificate[] chain)</code>
143     * method
144     * Assertion: stores KeyEntry.
145     */
146    public void testSetKeyEntry() throws Exception {
147        assertTrue(NotSupportMsg, KSSupported);
148
149        KeyStore[] kss = createKS();
150        assertNotNull("KeyStore objects were not created", kss);
151        byte[] kk = { (byte) 1, (byte) 2, (byte) 127, (byte) 77 };
152        String alias = "keyEntry";
153        char[] pwd = new char[0];
154        byte[] res;
155        Certificate certs[] = {
156                new KeyStoreTestSupport.MCertificate(alias, kk),
157                new KeyStoreTestSupport.MCertificate(alias, kk) };
158        for (int i = 0; i < kss.length; i++) {
159            kss[i].load(null, null);
160            try {
161                kss[i].setKeyEntry("proba", null, null);
162                fail("KeyStoreException must be thrown");
163            } catch (KeyStoreException e) {
164            }
165            kss[i].setKeyEntry(alias, kk, certs);
166            res = kss[i].getKey(alias, pwd).getEncoded();
167            assertEquals(kk.length, res.length);
168            for (int j = 0; j < res.length; j++) {
169                assertEquals(res[j], kk[j]);
170            }
171            assertEquals(kss[i].getCertificateChain(alias).length, certs.length);
172            kss[i].setKeyEntry(alias, kk, null);
173            res = kss[i].getKey(alias, pwd).getEncoded();
174            assertEquals(kk.length, res.length);
175            for (int j = 0; j < res.length; j++) {
176                assertEquals(res[j], kk[j]);
177            }
178            assertNull(kss[i].getCertificateChain(alias));
179        }
180    }
181
182    /**
183     * Test for <code>getDefaultType()</code> method Assertion: returns
184     * default security key store type or "jks" string
185     */
186    public void testKeyStore01() {
187        String propName = "keystore.type";
188        String defKSType = Security.getProperty(propName);
189        String dType = KeyStore.getDefaultType();
190        String resType = defKSType;
191        if (resType == null) {
192            resType = defaultType;
193        }
194        assertNotNull("Default type have not be null", dType);
195        assertEquals("Incorrect default type", dType, resType);
196
197        if (defKSType == null) {
198            Security.setProperty(propName, defaultType);
199            dType = KeyStore.getDefaultType();
200            resType = Security.getProperty(propName);
201            assertNotNull("Incorrect default type", resType);
202            assertNotNull("Default type have not be null", dType);
203            assertEquals("Incorrect default type", dType, resType);
204        }
205    }
206
207    /**
208     * Test for <code>getInstance(String type)</code> method
209     * Assertion:
210     * throws NullPointerException when type is null
211     * throws KeyStoreException when type is not available
212     *
213     */
214    public void testKeyStore02() throws KeyStoreException {
215        String[] invalidValues =  SpiEngUtils.invalidValues;
216        try {
217            KeyStore.getInstance(null);
218            fail("NullPointerException must be thrown when type is null");
219        } catch (NullPointerException e) {
220        }
221        for (int i = 0; i < invalidValues.length; i++) {
222            try {
223                KeyStore.getInstance(invalidValues[i]);
224                fail("KeyStoreException must be thrown (type: ".concat(
225                        invalidValues[i]).concat(" )"));
226            } catch (KeyStoreException e) {
227            }
228        }
229    }
230
231    public void testKeyStorePPGetPassword() {
232        // Regression for HARMONY-1539
233        // no exception expected
234        assertNull(new KeyStore.PasswordProtection(null).getPassword());
235        char[] password = new char[] {'a', 'b', 'c'};
236        KeyStore.PasswordProtection pp = new KeyStore.PasswordProtection(password);
237        assertNotSame(pp.getPassword(), password);
238        assertSame(pp.getPassword(), pp.getPassword());
239
240    }
241
242
243    /*
244     * java.security.KeyStoreSpi.engineEntryInstanceOf(String, Class<? extends Entry>)
245     */
246    public void testEngineEntryInstanceOf() throws Exception {
247        //Regression for HARMONY-615
248
249        // create a KeyStore
250        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
251        keyStore.load(null, "pwd".toCharArray());
252
253        // generate a key
254        KeyGenerator keyGen = KeyGenerator.getInstance("DES");
255        keyGen.init(56);
256        SecretKey secretKey = keyGen.generateKey();
257
258        // put the key into keystore
259        String alias = "alias";
260        keyStore.setKeyEntry(alias, secretKey, "pwd".toCharArray(), null);
261
262        // check if it is a secret key
263        assertTrue(keyStore.entryInstanceOf(alias,
264                KeyStore.SecretKeyEntry.class));
265
266        // check if it is NOT a private key
267        assertFalse(keyStore.entryInstanceOf(alias,
268                KeyStore.PrivateKeyEntry.class));
269    }
270
271    /**
272     * java.security.KeyStore.TrustedCertificateEntry.toString()
273     */
274    public void testKeyStoreTCToString() {
275           // Regression for HARMONY-1542
276           // no exception expected
277        class TestX509Certificate extends X509Certificate {
278            private static final long serialVersionUID = 1L;
279            public void checkValidity() throws CertificateExpiredException,CertificateNotYetValidException {}
280            public void checkValidity(Date p) throws CertificateExpiredException, CertificateNotYetValidException {}
281            public int getVersion() {
282                    return 0;
283            }
284            public BigInteger getSerialNumber() {
285                    return null;
286            }
287            public Principal getIssuerDN() {
288                    return null;
289            }
290            public Principal getSubjectDN() {
291                    return null;
292            }
293            public Date getNotBefore() {
294                    return null;
295            }
296            public Date getNotAfter() {
297                    return null;
298            }
299            public byte[] getTBSCertificate() throws CertificateEncodingException {
300                    return null;
301            }
302            public byte[] getSignature() {
303                    return null;
304            }
305            public String getSigAlgName() {
306                    return null;
307            }
308            public String getSigAlgOID() {
309                    return null;
310            }
311            public byte[] getSigAlgParams() {
312                    return null;
313            }
314            public boolean[] getIssuerUniqueID() {
315                    return null;
316            }
317            public boolean[] getSubjectUniqueID() {
318                    return null;
319            }
320            public boolean[] getKeyUsage() {
321                    return null;
322            }
323            public int getBasicConstraints() {
324                    return 0;
325            }
326            public byte[] getEncoded() throws CertificateEncodingException {
327                    return null;
328            }
329            public void verify(PublicKey p)
330                    throws CertificateException,
331                    NoSuchAlgorithmException,
332                    InvalidKeyException,
333                    NoSuchProviderException,
334                    SignatureException
335            {}
336            public void verify(PublicKey p0, String p1)
337                    throws CertificateException,
338                    NoSuchAlgorithmException,
339                    InvalidKeyException,
340                    NoSuchProviderException,
341                    SignatureException
342            {}
343            public String toString() {
344                    return null;
345            }
346            public PublicKey getPublicKey() {
347                    return null;
348            }
349            public boolean hasUnsupportedCriticalExtension() {
350                    return false;
351            }
352            public Set getCriticalExtensionOIDs() {
353                    return null;
354            }
355            public Set getNonCriticalExtensionOIDs() {
356                    return null;
357            }
358            public byte[] getExtensionValue(String p) {
359                    return null;
360            }
361        }
362        assertNotNull(new KeyStore.TrustedCertificateEntry(new TestX509Certificate()).toString());
363    }
364}
365