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
18package org.apache.harmony.security.tests.java.security;
19
20import java.security.InvalidParameterException;
21import java.security.Provider;
22import java.security.Security;
23import java.util.Hashtable;
24import java.util.Iterator;
25import java.util.Map;
26import java.util.Set;
27
28import tests.support.Support_ProviderTrust;
29import tests.support.Support_TestProvider;
30
31public class Security2Test extends junit.framework.TestCase {
32
33    /**
34     * @tests java.security.Security#getProviders(java.lang.String)
35     */
36    public void test_getProvidersLjava_lang_String() {
37        // Test for method void
38        // java.security.Security.getProviders(java.lang.String)
39
40        Hashtable allSupported = new Hashtable();
41        Provider[] allProviders = Security.getProviders();
42
43        // Add all non-alias entries to allSupported
44        for (int i = 0; i < allProviders.length; i++) {
45            Provider provider = allProviders[i];
46            Iterator it = provider.entrySet().iterator();
47            while (it.hasNext()) {
48                Map.Entry entry = (Map.Entry) it.next();
49                String key = (String) entry.getKey();
50                // No aliases and no provider data
51                if (!isAlias(key) && !isProviderData(key)) {
52                    addOrIncrementTable(allSupported, key);
53                }
54            }// end while more entries
55        }// end for all providers
56
57        // Now walk through aliases. If an alias has actually been added
58        // to the allSupported table then increment the count of the
59        // entry that is being aliased.
60        for (int i = 0; i < allProviders.length; i++) {
61            Provider provider = allProviders[i];
62            Iterator it = provider.entrySet().iterator();
63            while (it.hasNext()) {
64                Map.Entry entry = (Map.Entry) it.next();
65                String key = (String) entry.getKey();
66                if (isAlias(key)) {
67                    String aliasVal = key.substring("ALG.ALIAS.".length());
68                    String aliasKey = aliasVal.substring(0, aliasVal
69                            .indexOf('.') + 1)
70                            + entry.getValue();
71                    // Skip over nonsense alias declarations where alias and
72                    // aliased are identical. Such entries can occur.
73                    if (!aliasVal.equals(aliasKey)) {
74                        // Has a real entry been added for aliasValue ?
75                        if (allSupported.containsKey(aliasVal)) {
76                            // Add 1 to the provider count of the thing being
77                            // aliased
78                            addOrIncrementTable(allSupported, aliasKey);
79                        }
80                    }
81                }
82            }// end while more entries
83        }// end for all providers
84
85        Provider provTest[] = null;
86        Iterator it = allSupported.keySet().iterator();
87        while (it.hasNext()) {
88            String filterString = (String) it.next();
89            try {
90                provTest = Security.getProviders(filterString);
91                int expected = ((Integer) allSupported.get(filterString))
92                        .intValue();
93                assertEquals(
94                        "Unexpected number of providers returned for filter "
95                                + filterString, expected, provTest.length);
96            } catch (InvalidParameterException e) {
97                // NO OP
98            }
99        }// end while
100
101        // exception
102        try {
103            provTest = Security.getProviders("Signature.SHA1withDSA :512");
104            fail("InvalidParameterException should be thrown <Signature.SHA1withDSA :512>");
105        } catch (InvalidParameterException e) {
106            // Expected
107        }
108    }
109
110    /**
111     * @param key
112     * @return
113     */
114    private boolean isProviderData(String key) {
115        return key.toUpperCase().startsWith("PROVIDER.");
116    }
117
118    /**
119     * @param key
120     * @return
121     */
122    private boolean isAlias(String key) {
123        return key.toUpperCase().startsWith("ALG.ALIAS.");
124    }
125
126    /**
127     * @param table
128     * @param key
129     */
130    private void addOrIncrementTable(Hashtable table, String key) {
131        if (table.containsKey(key)) {
132            Integer before = (Integer) table.get(key);
133            table.put(key, new Integer(before.intValue() + 1));
134        } else {
135            table.put(key, new Integer(1));
136        }
137    }
138
139    /**
140     * @param filterMap
141     * @return
142     */
143    private int getProvidersCount(Map filterMap) {
144        int result = 0;
145        Provider[] allProviders = Security.getProviders();
146
147        // for each provider
148        for (int i = 0; i < allProviders.length; i++) {
149            Provider provider = allProviders[i];
150            Set allProviderKeys = provider.keySet();
151            boolean noMatchFoundForFilterEntry = false;
152
153            // for each filter item
154            Set allFilterKeys = filterMap.keySet();
155            Iterator fkIter = allFilterKeys.iterator();
156            while (fkIter.hasNext()) {
157                String filterString = ((String) fkIter.next()).trim();
158
159                // Remove any "=" characters that may be on the end of the
160                // map keys (no, I don't know why they might be there either
161                // but I have seen them)
162                if (filterString.endsWith("=")) {
163                    filterString = filterString.substring(0, filterString
164                            .length() - 1);
165                }
166
167                if (filterString != null) {
168                    if (filterString.indexOf(' ') == -1) {
169                        // Is this filter string in the keys of the
170                        // current provider ?
171                        if (!allProviderKeys.contains(filterString)) {
172                            // Check that the key is not contained as an
173                            // alias.
174                            if (!allProviderKeys.contains("Alg.Alias."
175                                    + filterString)) {
176                                noMatchFoundForFilterEntry = true;
177                                break; // out of while loop
178                            }
179                        }
180                    } else {
181                        // handle filter strings with attribute names
182                        if (allProviderKeys.contains(filterString)) {
183                            // Does the corresponding values match ?
184                            String filterVal = (String) filterMap
185                                    .get(filterString);
186                            String providerVal = (String) provider
187                                    .get(filterString);
188                            if (providerVal == null
189                                    || !providerVal.equals(filterVal)) {
190                                noMatchFoundForFilterEntry = true;
191                                break; // out of while loop
192                            }
193                        }// end if filter string with named attribute is
194                        // found
195                    }// end else
196                }// end if non-null key
197            }// end while there are more filter strings for current map
198
199            if (!noMatchFoundForFilterEntry) {
200                // Current provider is a match for the filterMap
201                result++;
202            }
203        }// end for each provider
204
205        return result;
206    }
207
208    /**
209     * @tests java.security.Security#getProviders(java.util.Map)
210     */
211    public void test_getProvidersLjava_util_Map() {
212        // Test for method void
213        // java.security.Security.getProviders(java.util.Map)
214
215        Map filter = new Hashtable();
216        filter.put("KeyStore.BKS", "");
217        filter.put("Signature.SHA1withDSA", "");
218        Provider provTest[] = Security.getProviders(filter);
219        if (provTest == null) {
220            assertEquals("Filter : <KeyStore.BKS>,<Signature.SHA1withDSA>",
221                    0, getProvidersCount(filter));
222        } else {
223            assertEquals("Filter : <KeyStore.BKS>,<Signature.SHA1withDSA>",
224                    getProvidersCount(filter), provTest.length);
225        }
226
227        filter = new Hashtable();
228        filter.put("MessageDigest.MD2", "");
229        filter.put("CertificateFactory.X.509", "");
230        filter.put("KeyFactory.RSA", "");
231        provTest = Security.getProviders(filter);
232        if (provTest == null) {
233            assertEquals("Filter : <MessageDigest.MD2>,<CertificateFactory.X.509>,<KeyFactory.RSA>",
234                    0, getProvidersCount(filter));
235        } else {
236            assertEquals(
237                    "Filter : <MessageDigest.MD2>,<CertificateFactory.X.509>,<KeyFactory.RSA>",
238                    getProvidersCount(filter), provTest.length);
239        }
240
241        filter = new Hashtable();
242        filter.put("MessageDigest.SHA", "");
243        filter.put("CertificateFactory.X.509", "");
244        provTest = Security.getProviders(filter);
245        if (provTest == null) {
246            assertEquals("Filter : <MessageDigest.SHA><CertificateFactory.X.509>",
247                    0, getProvidersCount(filter));
248        } else {
249            assertEquals(
250                    "Filter : <MessageDigest.SHA><CertificateFactory.X.509>",
251                    getProvidersCount(filter), provTest.length);
252        }
253
254        filter = new Hashtable();
255        filter.put("CertificateFactory.X509", "");
256        provTest = Security.getProviders(filter);
257        if (provTest == null) {
258            assertEquals("Filter : <CertificateFactory.X509>",
259                    0, getProvidersCount(filter));
260        } else {
261            assertEquals("Filter : <CertificateFactory.X509>",
262                    getProvidersCount(filter), provTest.length);
263        }
264
265        filter = new Hashtable();
266        filter.put("Provider.id name", "DRLCertFactory");
267        provTest = Security.getProviders(filter);
268        assertNull("Filter : <Provider.id name, DRLCertFactory >",
269                provTest);
270
271        // exception - no attribute name after the service.algorithm yet we
272        // still supply an expected value. This is not valid.
273        try {
274            filter = new Hashtable();
275            filter.put("Signature.SHA1withDSA", "512");
276            provTest = Security.getProviders(filter);
277            fail("InvalidParameterException should be thrown <Signature.SHA1withDSA><512>");
278        } catch (InvalidParameterException e) {
279            // Expected
280        }
281
282        // exception - space character in the service.algorithm pair. Not valid.
283        try {
284            filter = new Hashtable();
285            filter.put("Signature. KeySize", "512");
286            provTest = Security.getProviders(filter);
287            fail("InvalidParameterException should be thrown <Signature. KeySize><512>");
288        } catch (InvalidParameterException e) {
289            // Expected
290        }
291    }
292
293    /**
294     * @tests java.security.Security#removeProvider(java.lang.String)
295     */
296    public void test_removeProviderLjava_lang_String() {
297        // Test for method void
298        // java.security.Security.removeProvider(java.lang.String)
299        Provider test = new Support_TestProvider();
300        Provider entrust = new Support_ProviderTrust();
301        try {
302            // Make sure provider not already loaded. Should do nothing
303            // if not already loaded.
304            Security.removeProvider(test.getName());
305
306            // Now add it
307            int addResult = Security.addProvider(test);
308            assertTrue("Failed to add provider", addResult != -1);
309
310            Security.removeProvider(test.getName());
311            assertNull(
312                    "the provider TestProvider is found after it was removed",
313                    Security.getProvider(test.getName()));
314
315            // Make sure entrust provider not already loaded. Should do nothing
316            // if not already loaded.
317            Security.removeProvider(entrust.getName());
318
319            // Now add entrust
320            addResult = Security.addProvider(entrust);
321            assertTrue("Failed to add provider", addResult != -1);
322
323            Security.removeProvider(entrust.getName());
324            Provider provTest[] = Security.getProviders();
325            for (int i = 0; i < provTest.length; i++) {
326                assertTrue(
327                        "the provider entrust is found after it was removed",
328                        provTest[i].getName() != entrust.getName());
329            }
330        } finally {
331            // Tidy up - the following calls do nothing if the providers were
332            // already removed above.
333            Security.removeProvider(test.getName());
334            Security.removeProvider(entrust.getName());
335        }
336    }
337}
338