• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Boris V. Kuznetsov
20  * @version $Revision$
21  */
22 
23 package org.apache.harmony.security.tests.java.security;
24 
25 import libcore.test.annotation.NonCts;
26 import libcore.test.reasons.NonCtsReasons;
27 
28 import java.io.ByteArrayInputStream;
29 import java.io.ByteArrayOutputStream;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.PrintStream;
33 import java.security.NoSuchAlgorithmException;
34 import java.security.Permission;
35 import java.security.Provider;
36 import java.security.Security;
37 import java.security.SecurityPermission;
38 import java.security.Provider.Service;
39 import java.util.Collection;
40 import java.util.ConcurrentModificationException;
41 import java.util.HashMap;
42 import java.util.Iterator;
43 import java.util.Locale;
44 import java.util.Set;
45 import java.util.Map.Entry;
46 
47 import junit.framework.TestCase;
48 
49 /**
50  * Tests for <code>Provider</code> constructor and methods
51  *
52  */
53 public class ProviderTest extends TestCase {
54     /*
55      * Implementation note: The algorithm name ASH-1 might seem a bit strange,
56      * but since the algorithms cannot be uninstalled anymore we need to make
57      * sure there are not side-effects on other tests. Simply inserting SHA-1
58      * destroys the existing provider infrastructure.
59      */
60 
61     Provider[] storedProviders;
62 
63     Provider p;
64 
65     /*
66      * @see TestCase#setUp()
67      */
setUp()68     protected void setUp() throws Exception {
69         super.setUp();
70 
71         storedProviders = Security.getProviders();
72 
73         p = new MyProvider();
74     }
75 
76     @Override
tearDown()77     protected void tearDown() throws Exception {
78         p.remove("MessageDigest.ASH-1");
79         p.remove("MessageDigest.abc");
80         p.remove("Alg.Alias.MessageDigest.ASH1");
81 
82         for (Provider p: Security.getProviders()) {
83             Security.removeProvider(p.getName());
84         }
85 
86         for (Provider p: storedProviders) {
87             Security.addProvider(p);
88         }
89 
90         super.tearDown();
91     }
92 
93     /*
94      * Class under test for void Provider()
95      */
testProvider()96     public final void testProvider() {
97         if (!p.getProperty("Provider.id name").equals(
98                 String.valueOf(p.getName()))) {
99             fail("Incorrect \"Provider.id name\" value");
100         }
101         if (!p.getProperty("Provider.id version").equals(
102                 String.valueOf(p.getVersion()))) {
103             fail("Incorrect \"Provider.id version\" value");
104         }
105         if (!p.getProperty("Provider.id info").equals(
106                 String.valueOf(p.getInfo()))) {
107             fail("Incorrect \"Provider.id info\" value");
108         }
109         if (!p.getProperty("Provider.id className").equals(
110                 p.getClass().getName())) {
111             fail("Incorrect \"Provider.id className\" value");
112         }
113     }
114 
testClear()115     public final void testClear() {
116         p.clear();
117         assertNull(p.getProperty("MessageDigest.SHA-1"));
118     }
119 
120     /*
121      * Class under test for void Provider(String, double, String)
122      */
testProviderStringdoubleString()123     public final void testProviderStringdoubleString() {
124         Provider p = new MyProvider("Provider name", 123.456, "Provider info");
125         assertEquals("Provider name", p.getName());
126         assertEquals(123.456, p.getVersion(), 0L);
127         assertEquals("Provider info", p.getInfo());
128     }
129 
testGetName()130     public final void testGetName() {
131         assertEquals("MyProvider", p.getName());
132     }
133 
testGetVersion()134     public final void testGetVersion() {
135         assertEquals(1.0, p.getVersion(), 0L);
136     }
137 
testGetInfo()138     public final void testGetInfo() {
139         assertEquals("Provider for testing", p.getInfo());
140     }
141 
142     /*
143      * Class under test for void putAll(Map)
144      */
testPutAllMap()145     public final void testPutAllMap() {
146         HashMap hm = new HashMap();
147         hm.put("MessageDigest.SHA-1", "aaa.bbb.ccc.ddd");
148         hm.put("Property 1", "value 1");
149         hm.put("serviceName.algName attrName", "attrValue");
150         hm.put("Alg.Alias.engineClassName.aliasName", "standardName");
151         p.putAll(hm);
152         if (!"value 1".equals(p.getProperty("Property 1").trim()) ||
153                 !"attrValue".equals(p.getProperty("serviceName.algName attrName").trim()) ||
154                 !"standardName".equals(p.getProperty("Alg.Alias.engineClassName.aliasName").trim()) ||
155                 !"aaa.bbb.ccc.ddd".equals(p.getProperty("MessageDigest.SHA-1").trim()) ) {
156             fail("Incorrect property value");
157         }
158     }
159 
160     /*
161      * Class under test for Set entrySet()
162      */
testEntrySet()163     public final void testEntrySet() {
164         p.put("MessageDigest.SHA-256", "aaa.bbb.ccc.ddd");
165 
166         Set s = p.entrySet();
167         try {
168             s.clear();
169             fail("Must return unmodifiable set");
170         } catch (UnsupportedOperationException e) {
171         }
172 
173         assertEquals("Incorrect set size", 8, s.size());
174 
175         for (Iterator it = s.iterator(); it.hasNext();) {
176             Entry e = (Entry)it.next();
177             String key = (String)e.getKey();
178             String val = (String)e.getValue();
179             if (key.equals("MessageDigest.SHA-1") && val.equals("SomeClassName")) {
180                 continue;
181             }
182             if (key.equals("Alg.Alias.MessageDigest.SHA1") && val.equals("SHA-1")) {
183                 continue;
184             }
185             if (key.equals("MessageDigest.abc") && val.equals("SomeClassName")) {
186                 continue;
187             }
188             if (key.equals("Provider.id className") && val.equals(p.getClass().getName())) {
189                 continue;
190             }
191             if (key.equals("Provider.id name") && val.equals("MyProvider")) {
192                 continue;
193             }
194             if (key.equals("MessageDigest.SHA-256") && val.equals("aaa.bbb.ccc.ddd")) {
195                 continue;
196             }
197             if (key.equals("Provider.id version") && val.equals("1.0")) {
198                 continue;
199             }
200             if (key.equals("Provider.id info") && val.equals("Provider for testing")) {
201                 continue;
202             }
203             fail("Incorrect set");
204         }
205     }
206 
testForEach()207     public final void testForEach() {
208         p.put("MessageDigest.SHA-1", "aaa.bbb.ccc.ddd");
209         p.put("MessageDigest.abc", "value 1");
210 
211         HashMap<String, String> hm = new HashMap<>();
212         p.forEach((k,v)-> hm.put((String)k, (String)v));
213 
214         assertEquals(p.size(), hm.size());
215         for(String key : hm.keySet()) {
216           assertEquals(p.get(key), hm.get(key));
217         }
218     }
219 
testForEachNPE()220     public void testForEachNPE() throws Exception {
221         try {
222             p.forEach(null);
223             fail();
224         } catch(NullPointerException expected) {}
225     }
226 
227     @NonCts(bug = 259671905, reason = NonCtsReasons.NON_BREAKING_BEHAVIOR_FIX)
testForEachCME()228     public void testForEachCME() throws Exception {}
229 
230     /*
231      * Class under test for Set keySet()
232      */
testKeySet()233     public final void testKeySet() {
234         p.put("MessageDigest.SHA-256", "aaa.bbb.ccc.ddd");
235 
236         Set<Object> s = p.keySet();
237         try {
238             s.clear();
239         } catch (UnsupportedOperationException e) {
240         }
241         Set s1 = p.keySet();
242 
243         assertNotSame(s, s1);
244         assertFalse(s1.isEmpty());
245         assertEquals(8, s1.size());
246 
247         assertTrue(s1.contains("MessageDigest.SHA-256"));
248         assertTrue(s1.contains("MessageDigest.SHA-1"));
249         assertTrue(s1.contains("Alg.Alias.MessageDigest.SHA1"));
250         assertTrue(s1.contains("MessageDigest.abc"));
251         assertTrue(s1.contains("Provider.id info"));
252         assertTrue(s1.contains("Provider.id className"));
253         assertTrue(s1.contains("Provider.id version"));
254         assertTrue(s1.contains("Provider.id name"));
255     }
256 
257     /*
258      * Class under test for Collection values()
259      */
testValues()260     public final void testValues() {
261         p.put("MessageDigest.ASH-256", "aaa.bbb.ccc.ddd");
262 
263         Collection<Object> c = p.values();
264         try {
265             c.clear();
266         } catch (UnsupportedOperationException e) {
267         }
268         Collection c1 = p.values();
269 
270         assertNotSame(c, c1);
271         assertFalse(c1.isEmpty());
272         assertEquals(8, c1.size());
273 
274         assertTrue(c1.contains("MyProvider"));
275         assertTrue(c1.contains("aaa.bbb.ccc.ddd"));
276         assertTrue(c1.contains("Provider for testing"));
277         assertTrue(c1.contains("1.0"));
278         assertTrue(c1.contains("SomeClassName"));
279         assertTrue(c1.contains("SHA-1"));
280         assertTrue(c1.contains(p.getClass().getName()));
281     }
282 
283     /*
284      * Class under test for Object put(Object, Object)
285      */
testPutObjectObject()286     public final void testPutObjectObject() {
287         p.put("MessageDigest.SHA-1", "aaa.bbb.ccc.ddd");
288         p.put("Type.Algorithm", "className");
289         assertEquals("aaa.bbb.ccc.ddd", p.getProperty("MessageDigest.SHA-1")
290                 .trim());
291 
292         Set services = p.getServices();
293         assertEquals(3, services.size());
294 
295         for (Iterator it = services.iterator(); it.hasNext();) {
296             Provider.Service s = (Provider.Service)it.next();
297             if ("Type".equals(s.getType()) &&
298                     "Algorithm".equals(s.getAlgorithm()) &&
299                     "className".equals(s.getClassName())) {
300                 continue;
301             }
302             if ("MessageDigest".equals(s.getType()) &&
303                     "SHA-1".equals(s.getAlgorithm()) &&
304                     "aaa.bbb.ccc.ddd".equals(s.getClassName())) {
305                 continue;
306             }
307             if ("MessageDigest".equals(s.getType()) &&
308                     "abc".equals(s.getAlgorithm()) &&
309                     "SomeClassName".equals(s.getClassName())) {
310                 continue;
311             }
312             fail("Incorrect service");
313         }
314     }
315 
316     /*
317      * Class under test for Object remove(Object)
318      */
testRemoveObject()319     public final void testRemoveObject() {
320         Object o = p.remove("MessageDigest.SHA-1");
321 
322         assertEquals("SomeClassName", o);
323         assertNull(p.getProperty("MessageDigest.SHA-1"));
324         assertEquals(1, p.getServices().size());
325     }
326 
testService1()327     public final void testService1() {
328         p.put("MessageDigest.SHA-1", "AnotherClassName");
329         Provider.Service s = p.getService("MessageDigest", "SHA-1");
330         assertEquals("AnotherClassName", s.getClassName());
331     }
332 
testGetServiceCaseSensitivity()333     public final void testGetServiceCaseSensitivity() {
334         p.put("i.I", "foo");
335 
336         Locale defaultLocale = Locale.getDefault();
337         Locale.setDefault(new Locale("tr", "TR"));
338         try {
339             assertEquals("foo", p.getService("i", "i").getClassName());
340             assertEquals("foo", p.getService("i", "I").getClassName());
341             assertNull(p.getService("\u0130", "\u0130")); // Turkish dotless i and dotted I
342             assertNull(p.getService("\u0131", "\u0131"));
343         } finally {
344             Locale.setDefault(defaultLocale);
345         }
346     }
347 
348     // Regression for HARMONY-2760.
testConstructor()349     public void testConstructor() {
350         MyProvider myProvider = new MyProvider(null, 1, null);
351         assertNull(myProvider.getName());
352         assertNull(myProvider.getInfo());
353         assertEquals("null", myProvider.getProperty("Provider.id name"));
354         assertEquals("null", myProvider.getProperty("Provider.id info"));
355     }
356 
357     class MyProvider extends Provider {
MyProvider()358         MyProvider() {
359             super("MyProvider", 1.0, "Provider for testing");
360             put("MessageDigest.SHA-1", "SomeClassName");
361             put("MessageDigest.abc", "SomeClassName");
362             put("Alg.Alias.MessageDigest.SHA1", "SHA-1");
363         }
364 
MyProvider(String name, double version, String info)365         MyProvider(String name, double version, String info) {
366             super(name, version, info);
367         }
368 
369         // BEGIN Android-added
putService(Provider.Service s)370         public void putService(Provider.Service s) {
371             super.putService(s);
372         }
373         // END Android-added
374 
375         // BEGIN Android-added
removeService(Provider.Service s)376         public void removeService(Provider.Service s) {
377             super.removeService(s);
378         }
379         // END Android-added
380 
381         // BEGIN Android-added
getNumServices()382         public int getNumServices() {
383             return getServices().size();
384         }
385         // END Android-added
386     }
387 
388     // BEGIN Android-added
testService2()389     public final void testService2() {
390         Provider[] pp = Security.getProviders("MessageDigest.ASH-1");
391         if (pp == null) {
392             return;
393         }
394         Provider p2 = pp[0];
395         String old = p2.getProperty("MessageDigest.ASH-1");
396         p2.put("MessageDigest.ASH-1", "AnotherClassName");
397         Provider.Service s = p2.getService("MessageDigest", "ASH-1");
398         if (!"AnotherClassName".equals(s.getClassName())) {
399             fail("Incorrect class name " + s.getClassName());
400         }
401         try {
402             s.newInstance(null);
403             fail("No expected NoSuchAlgorithmException");
404         } catch (NoSuchAlgorithmException e) {
405         }
406     }
407     // END Android-added
408 
409     // BEGIN Android-added
testGetServices()410     public final void testGetServices() {
411         MyProvider myProvider = new MyProvider(null, 1, null);
412         Set<Provider.Service> services = myProvider.getServices();
413         assertEquals(0, services.size());
414 
415         Provider.Service s[] = new Provider.Service[3];
416 
417         s[0] = new Provider.Service(myProvider, "type1", "algorithm1", "className1",
418                 null, null);
419         s[1] = new Provider.Service(myProvider, "type2", "algorithm2", "className2",
420                 null, null);
421         s[2] = new Provider.Service(myProvider, "type3", "algorithm3", "className3",
422                 null, null);
423         myProvider.putService(s[0]);
424         myProvider.putService(s[1]);
425         assertEquals(2, myProvider.getNumServices());
426         Set<Service> actual = myProvider.getServices();
427 
428         assertTrue(actual.contains(s[0]));
429         assertTrue(actual.contains(s[1]));
430         assertTrue(!actual.contains(s[2]));
431 
432         myProvider.removeService(s[1]);
433         actual = myProvider.getServices();
434         assertEquals(1, myProvider.getNumServices());
435 
436         assertTrue(actual.contains(s[0]));
437         assertTrue(!actual.contains(s[1]));
438         assertTrue(!actual.contains(s[2]));
439 
440         myProvider.putService(s[2]);
441         actual = myProvider.getServices();
442         assertEquals(2, myProvider.getNumServices());
443         assertTrue(actual.contains(s[0]));
444         assertTrue(!actual.contains(s[1]));
445         assertTrue(actual.contains(s[2]));
446     }
447     // END Android-added
448 
449     // BEGIN Android-added
testPutService()450     public final void testPutService() {
451         MyProvider myProvider = new MyProvider(null, 1, null);
452         Provider.Service s[] = new Provider.Service[3];
453 
454         s[0] = new Provider.Service(myProvider, "type1", "algorithm1", "className1",
455                 null, null);
456         s[1] = new Provider.Service(myProvider, "type2", "algorithm2", "className2",
457                 null, null);
458         s[2] = new Provider.Service(myProvider, "type3", "algorithm3", "className3",
459                 null, null);
460         myProvider.putService(s[0]);
461         myProvider.putService(s[1]);
462         assertEquals(2, myProvider.getNumServices());
463         Set<Service> actual = myProvider.getServices();
464 
465         assertTrue(actual.contains(s[0]));
466         assertTrue(actual.contains(s[1]));
467         assertTrue(!actual.contains(s[2]));
468 
469         myProvider.removeService(s[1]);
470         assertEquals(1, myProvider.getNumServices());
471         actual = myProvider.getServices();
472 
473         assertTrue(actual.contains(s[0]));
474         assertTrue(!actual.contains(s[1]));
475         assertTrue(!actual.contains(s[2]));
476 
477         myProvider.putService(s[2]);
478         actual = myProvider.getServices();
479         assertEquals(2, myProvider.getNumServices());
480         assertTrue(actual.contains(s[0]));
481         assertTrue(!actual.contains(s[1]));
482         assertTrue(actual.contains(s[2]));
483 
484         myProvider.putService(s[2]);
485         actual = myProvider.getServices();
486         assertEquals(2, myProvider.getNumServices());
487         assertTrue(actual.contains(s[0]));
488         assertTrue(!actual.contains(s[1]));
489         assertTrue(actual.contains(s[2]));
490 
491         try {
492             myProvider.putService(null);
493             fail("NullPointerException expected");
494         } catch (NullPointerException e) {
495             // expected
496         }
497     }
498     // END Android-added
499 
500     // BEGIN Android-added
testRemoveService()501     public final void testRemoveService() {
502         MyProvider myProvider = new MyProvider(null, 1, null);
503         try {
504             myProvider.removeService(null);
505             fail("NullPoiterException expected");
506         } catch (NullPointerException e) {
507             // expected
508         }
509 
510         Provider.Service s[] = new Provider.Service[3];
511 
512         s[0] = new Provider.Service(myProvider, "type0", "algorithm0", "className0",
513                 null, null);
514         s[1] = new Provider.Service(myProvider, "type1", "algorithm1", "className1",
515                 null, null);
516         s[2] = new Provider.Service(myProvider, "type2", "algorithm2", "className2",
517                 null, null);
518 
519         try {
520             myProvider.removeService(s[0]);
521         } catch (NullPointerException e) {
522             fail("Unexpected exception");
523         }
524 
525         myProvider.putService(s[0]);
526         myProvider.putService(s[1]);
527         myProvider.putService(s[2]);
528         assertEquals(3, myProvider.getNumServices());
529         Set<Service> actual = myProvider.getServices();
530 
531         assertTrue(actual.contains(s[0]));
532         assertTrue(actual.contains(s[1]));
533         assertTrue(actual.contains(s[2]));
534 
535         myProvider.removeService(s[1]);
536         assertEquals(2, myProvider.getNumServices());
537         actual = myProvider.getServices();
538 
539         assertTrue(actual.contains(s[0]));
540         assertTrue(!actual.contains(s[1]));
541         assertTrue(actual.contains(s[2]));
542 
543         myProvider.removeService(s[0]);
544         assertEquals(1, myProvider.getNumServices());
545         actual = myProvider.getServices();
546 
547         assertTrue(!actual.contains(s[0]));
548         assertTrue(!actual.contains(s[1]));
549         assertTrue(actual.contains(s[2]));
550 
551         myProvider.removeService(s[2]);
552         assertEquals(0, myProvider.getNumServices());
553         actual = myProvider.getServices();
554 
555         assertTrue(!actual.contains(s[0]));
556         assertTrue(!actual.contains(s[1]));
557         assertTrue(!actual.contains(s[2]));
558 
559         try {
560             myProvider.removeService(null);
561             fail("NullPoiterException expected");
562         } catch (NullPointerException e) {
563             // expected
564         }
565     }
566     // END Android-added
567 
568     // BEGIN Android-added
testLoad()569     public final void testLoad() throws IOException {
570         InputStream is = new ByteArrayInputStream(writeProperties());
571         MyProvider myProvider = new MyProvider("name", 1, "info");
572         myProvider.load(is);
573         assertEquals("tests.security", myProvider.get("test.pkg"));
574         assertEquals("Unit Tests", myProvider.get("test.proj"));
575         assertNull(myProvider.get("#commented.entry"));
576 
577         assertEquals("info", myProvider.get("Provider.id info"));
578         String className = myProvider.getClass().toString();
579         assertEquals(
580                 className.substring("class ".length(), className.length()),
581                 myProvider.get("Provider.id className"));
582         assertEquals("1.0", myProvider.get("Provider.id version"));
583 
584         try {
585             myProvider.load((InputStream) null);
586             fail("NullPointerException expected");
587         } catch (NullPointerException e) {
588             // expected
589         }
590     }
591     // END Android-added
592 
593     // BEGIN Android-added
testLoad2()594     public final void testLoad2() {
595         class TestInputStream extends InputStream {
596             @Override
597             public int read() throws IOException {
598                 throw new IOException();
599             }
600         }
601 
602         MyProvider p = new MyProvider();
603         try {
604             p.load(new TestInputStream());
605             fail("expected IOException");
606         } catch (IOException e) {
607             // expected
608         }
609     }
610     // END Android-added
611 
612     // BEGIN Android-added
writeProperties()613     protected byte[] writeProperties() {
614         ByteArrayOutputStream bout = new ByteArrayOutputStream();
615         PrintStream ps = new PrintStream(bout);
616         ps.println("#commented.entry=Bogus");
617         ps.println("test.pkg=tests.security");
618         ps.println("test.proj=Unit Tests");
619         ps.close();
620         return bout.toByteArray();
621     }
622     // END Android-added
623 
624     // BEGIN Android-added
625     static class TestSecurityManager extends SecurityManager {
626         boolean called = false;
627         private final String permissionName;
628 
TestSecurityManager(String permissionName)629         public TestSecurityManager(String permissionName) {
630             this.permissionName = permissionName;
631         }
632 
633         @Override
checkPermission(Permission permission)634         public void checkPermission(Permission permission) {
635             if (permission instanceof SecurityPermission) {
636                 if (permissionName.equals(permission.getName())) {
637                     called = true;
638                 }
639             }
640         }
641     }
642     // END Android-added
643 }
644