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 */
21
22package org.apache.harmony.security.tests.java.security;
23
24import java.io.IOException;
25import java.security.KeyStore;
26import java.security.KeyStoreException;
27import java.security.Provider;
28import java.security.Security;
29import java.security.SignatureException;
30import java.security.Principal;
31import java.security.PublicKey;
32import java.security.InvalidKeyException;
33import java.security.NoSuchProviderException;
34import java.security.NoSuchAlgorithmException;
35import java.security.cert.Certificate;
36import java.security.cert.CertificateException;
37import java.security.cert.CertificateEncodingException;
38import java.security.cert.CertificateExpiredException;
39import java.security.cert.CertificateNotYetValidException;
40import java.security.cert.X509Certificate;
41import java.util.Date;
42import java.util.Set;
43import java.math.BigInteger;
44
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    public void testKeyStore02() throws KeyStoreException {
214        String[] invalidValues = SpiEngUtils.invalidValues;
215        try {
216            KeyStore.getInstance(null);
217            fail("NullPointerException must be thrown when type is null");
218        } catch (NullPointerException e) {
219        }
220        for (int i = 0; i < invalidValues.length; i++) {
221            try {
222                KeyStore.getInstance(invalidValues[i]);
223                fail("KeyStoreException must be thrown (type: ".concat(
224                        invalidValues[i]).concat(" )"));
225            } catch (KeyStoreException e) {
226            }
227        }
228    }
229
230    public void testKeyStorePPGetPassword() {
231        // Regression for HARMONY-1539
232        // no exception expected
233        assertNull(new KeyStore.PasswordProtection(null).getPassword());
234        char[] password = new char[] { 'a', 'b', 'c' };
235        KeyStore.PasswordProtection pp = new KeyStore.PasswordProtection(password);
236        assertNotSame(pp.getPassword(), password);
237        assertSame(pp.getPassword(), pp.getPassword());
238
239    }
240
241
242    /*
243     * @tests java.security.KeyStoreSpi.engineEntryInstanceOf(String, Class<? extends Entry>)
244     */
245    public void testEngineEntryInstanceOf() throws Exception {
246        //Regression for HARMONY-615
247
248        // create a KeyStore
249        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
250        keyStore.load(null, "pwd".toCharArray());
251
252        // generate a key
253        KeyGenerator keyGen = KeyGenerator.getInstance("DES");
254        keyGen.init(56);
255        SecretKey secretKey = keyGen.generateKey();
256
257        // put the key into keystore
258        String alias = "alias";
259        keyStore.setKeyEntry(alias, secretKey, "pwd".toCharArray(), null);
260
261        // check if it is a secret key
262        assertTrue(keyStore.entryInstanceOf(alias,
263                KeyStore.SecretKeyEntry.class));
264
265        // check if it is NOT a private key
266        assertFalse(keyStore.entryInstanceOf(alias,
267                KeyStore.PrivateKeyEntry.class));
268    }
269
270    /**
271     * @tests java.security.KeyStore.TrustedCertificateEntry.toString()
272     */
273    public void testKeyStoreTCToString() {
274        // Regression for HARMONY-1542
275        // no exception expected
276        class TestX509Certificate extends X509Certificate {
277            private static final long serialVersionUID = 1L;
278
279            public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException {
280            }
281
282            public void checkValidity(Date p) throws CertificateExpiredException, CertificateNotYetValidException {
283            }
284
285            public int getVersion() {
286                return 0;
287            }
288
289            public BigInteger getSerialNumber() {
290                return null;
291            }
292
293            public Principal getIssuerDN() {
294                return null;
295            }
296
297            public Principal getSubjectDN() {
298                return null;
299            }
300
301            public Date getNotBefore() {
302                return null;
303            }
304
305            public Date getNotAfter() {
306                return null;
307            }
308
309            public byte[] getTBSCertificate() throws CertificateEncodingException {
310                return null;
311            }
312
313            public byte[] getSignature() {
314                return null;
315            }
316
317            public String getSigAlgName() {
318                return null;
319            }
320
321            public String getSigAlgOID() {
322                return null;
323            }
324
325            public byte[] getSigAlgParams() {
326                return null;
327            }
328
329            public boolean[] getIssuerUniqueID() {
330                return null;
331            }
332
333            public boolean[] getSubjectUniqueID() {
334                return null;
335            }
336
337            public boolean[] getKeyUsage() {
338                return null;
339            }
340
341            public int getBasicConstraints() {
342                return 0;
343            }
344
345            public byte[] getEncoded() throws CertificateEncodingException {
346                return null;
347            }
348
349            public void verify(PublicKey p)
350                    throws CertificateException,
351                    NoSuchAlgorithmException,
352                    InvalidKeyException,
353                    NoSuchProviderException,
354                    SignatureException {
355            }
356
357            public void verify(PublicKey p0, String p1)
358                    throws CertificateException,
359                    NoSuchAlgorithmException,
360                    InvalidKeyException,
361                    NoSuchProviderException,
362                    SignatureException {
363            }
364
365            public String toString() {
366                return null;
367            }
368
369            public PublicKey getPublicKey() {
370                return null;
371            }
372
373            public boolean hasUnsupportedCriticalExtension() {
374                return false;
375            }
376
377            public Set getCriticalExtensionOIDs() {
378                return null;
379            }
380
381            public Set getNonCriticalExtensionOIDs() {
382                return null;
383            }
384
385            public byte[] getExtensionValue(String p) {
386                return null;
387            }
388        }
389        assertNotNull(new KeyStore.TrustedCertificateEntry(new TestX509Certificate()).toString());
390    }
391}
392