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