SecureClassLoaderTest.java revision cec4dd4b1d33f78997603d0f89c0d0e56e64dbcd
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 Alexander V. Astapchuk
20 * @version $Revision$
21 */
22
23package tests.java.security;
24
25import dalvik.annotation.KnownFailure;
26import dalvik.annotation.TestLevel;
27import dalvik.annotation.TestTargetClass;
28import dalvik.annotation.TestTargetNew;
29
30import junit.framework.TestCase;
31
32import java.net.URL;
33import java.net.URLClassLoader;
34import java.nio.ByteBuffer;
35import java.security.CodeSource;
36import java.security.Permission;
37import java.security.PermissionCollection;
38import java.security.ProtectionDomain;
39import java.security.SecureClassLoader;
40import java.security.cert.Certificate;
41@TestTargetClass(value=SecureClassLoader.class,
42        untestedMethods={
43            @TestTargetNew(
44                    level = TestLevel.NOT_FEASIBLE,
45                    notes = "cannot be tested",
46                    method = "defineClass",
47                    args = {
48                        java.lang.String.class, byte[].class, int.class,
49                        int.class, java.security.CodeSource.class}
50            ),
51            @TestTargetNew(
52                    level = TestLevel.NOT_FEASIBLE,
53                    notes = "cannot be tested",
54                    method = "defineClass",
55                    args = {
56                        java.lang.String.class, java.nio.ByteBuffer.class,
57                        java.security.CodeSource.class}
58            )
59})
60/**
61 * Unit test for SecureClassLoader.
62 *
63 */
64
65public class SecureClassLoaderTest extends TestCase {
66    /**
67     * A class name for the class presented as {@link #klassData bytecode below}
68     */
69    private static final String klassName = "HiWorld";
70
71    /**
72     * Some class presented as bytecode<br>
73     * Class src:<br>
74     * <p>
75     * <code>public class HiWorld {
76     *     public static void main(String[] args)
77     *         {System.out.println("Hi, world!"); }
78     *    }
79     * </code>
80     */
81
82    private static final byte[] klassData = { (byte) 0xCA, (byte) 0xFE,
83            (byte) 0xBA, (byte) 0xBE, (byte) 0x00, (byte) 0x00, (byte) 0x00,
84            (byte) 0x2E, (byte) 0x00, (byte) 0x22, (byte) 0x01, (byte) 0x00,
85            (byte) 0x07, (byte) 0x48, (byte) 0x69, (byte) 0x57, (byte) 0x6F,
86            (byte) 0x72, (byte) 0x6C, (byte) 0x64, (byte) 0x07, (byte) 0x00,
87            (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x10, (byte) 0x6A,
88            (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2F, (byte) 0x6C,
89            (byte) 0x61, (byte) 0x6E, (byte) 0x67, (byte) 0x2F, (byte) 0x4F,
90            (byte) 0x62, (byte) 0x6A, (byte) 0x65, (byte) 0x63, (byte) 0x74,
91            (byte) 0x07, (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x00,
92            (byte) 0x06, (byte) 0x3C, (byte) 0x69, (byte) 0x6E, (byte) 0x69,
93            (byte) 0x74, (byte) 0x3E, (byte) 0x01, (byte) 0x00, (byte) 0x03,
94            (byte) 0x28, (byte) 0x29, (byte) 0x56, (byte) 0x01, (byte) 0x00,
95            (byte) 0x04, (byte) 0x43, (byte) 0x6F, (byte) 0x64, (byte) 0x65,
96            (byte) 0x0C, (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x06,
97            (byte) 0x0A, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x08,
98            (byte) 0x01, (byte) 0x00, (byte) 0x0F, (byte) 0x4C, (byte) 0x69,
99            (byte) 0x6E, (byte) 0x65, (byte) 0x4E, (byte) 0x75, (byte) 0x6D,
100            (byte) 0x62, (byte) 0x65, (byte) 0x72, (byte) 0x54, (byte) 0x61,
101            (byte) 0x62, (byte) 0x6C, (byte) 0x65, (byte) 0x01, (byte) 0x00,
102            (byte) 0x12, (byte) 0x4C, (byte) 0x6F, (byte) 0x63, (byte) 0x61,
103            (byte) 0x6C, (byte) 0x56, (byte) 0x61, (byte) 0x72, (byte) 0x69,
104            (byte) 0x61, (byte) 0x62, (byte) 0x6C, (byte) 0x65, (byte) 0x54,
105            (byte) 0x61, (byte) 0x62, (byte) 0x6C, (byte) 0x65, (byte) 0x01,
106            (byte) 0x00, (byte) 0x04, (byte) 0x74, (byte) 0x68, (byte) 0x69,
107            (byte) 0x73, (byte) 0x01, (byte) 0x00, (byte) 0x09, (byte) 0x4C,
108            (byte) 0x48, (byte) 0x69, (byte) 0x57, (byte) 0x6F, (byte) 0x72,
109            (byte) 0x6C, (byte) 0x64, (byte) 0x3B, (byte) 0x01, (byte) 0x00,
110            (byte) 0x04, (byte) 0x6D, (byte) 0x61, (byte) 0x69, (byte) 0x6E,
111            (byte) 0x01, (byte) 0x00, (byte) 0x16, (byte) 0x28, (byte) 0x5B,
112            (byte) 0x4C, (byte) 0x6A, (byte) 0x61, (byte) 0x76, (byte) 0x61,
113            (byte) 0x2F, (byte) 0x6C, (byte) 0x61, (byte) 0x6E, (byte) 0x67,
114            (byte) 0x2F, (byte) 0x53, (byte) 0x74, (byte) 0x72, (byte) 0x69,
115            (byte) 0x6E, (byte) 0x67, (byte) 0x3B, (byte) 0x29, (byte) 0x56,
116            (byte) 0x01, (byte) 0x00, (byte) 0x10, (byte) 0x6A, (byte) 0x61,
117            (byte) 0x76, (byte) 0x61, (byte) 0x2F, (byte) 0x6C, (byte) 0x61,
118            (byte) 0x6E, (byte) 0x67, (byte) 0x2F, (byte) 0x53, (byte) 0x79,
119            (byte) 0x73, (byte) 0x74, (byte) 0x65, (byte) 0x6D, (byte) 0x07,
120            (byte) 0x00, (byte) 0x10, (byte) 0x01, (byte) 0x00, (byte) 0x03,
121            (byte) 0x6F, (byte) 0x75, (byte) 0x74, (byte) 0x01, (byte) 0x00,
122            (byte) 0x15, (byte) 0x4C, (byte) 0x6A, (byte) 0x61, (byte) 0x76,
123            (byte) 0x61, (byte) 0x2F, (byte) 0x69, (byte) 0x6F, (byte) 0x2F,
124            (byte) 0x50, (byte) 0x72, (byte) 0x69, (byte) 0x6E, (byte) 0x74,
125            (byte) 0x53, (byte) 0x74, (byte) 0x72, (byte) 0x65, (byte) 0x61,
126            (byte) 0x6D, (byte) 0x3B, (byte) 0x0C, (byte) 0x00, (byte) 0x12,
127            (byte) 0x00, (byte) 0x13, (byte) 0x09, (byte) 0x00, (byte) 0x11,
128            (byte) 0x00, (byte) 0x14, (byte) 0x01, (byte) 0x00, (byte) 0x0A,
129            (byte) 0x48, (byte) 0x69, (byte) 0x2C, (byte) 0x20, (byte) 0x77,
130            (byte) 0x6F, (byte) 0x72, (byte) 0x6C, (byte) 0x64, (byte) 0x21,
131            (byte) 0x08, (byte) 0x00, (byte) 0x16, (byte) 0x01, (byte) 0x00,
132            (byte) 0x13, (byte) 0x6A, (byte) 0x61, (byte) 0x76, (byte) 0x61,
133            (byte) 0x2F, (byte) 0x69, (byte) 0x6F, (byte) 0x2F, (byte) 0x50,
134            (byte) 0x72, (byte) 0x69, (byte) 0x6E, (byte) 0x74, (byte) 0x53,
135            (byte) 0x74, (byte) 0x72, (byte) 0x65, (byte) 0x61, (byte) 0x6D,
136            (byte) 0x07, (byte) 0x00, (byte) 0x18, (byte) 0x01, (byte) 0x00,
137            (byte) 0x07, (byte) 0x70, (byte) 0x72, (byte) 0x69, (byte) 0x6E,
138            (byte) 0x74, (byte) 0x6C, (byte) 0x6E, (byte) 0x01, (byte) 0x00,
139            (byte) 0x15, (byte) 0x28, (byte) 0x4C, (byte) 0x6A, (byte) 0x61,
140            (byte) 0x76, (byte) 0x61, (byte) 0x2F, (byte) 0x6C, (byte) 0x61,
141            (byte) 0x6E, (byte) 0x67, (byte) 0x2F, (byte) 0x53, (byte) 0x74,
142            (byte) 0x72, (byte) 0x69, (byte) 0x6E, (byte) 0x67, (byte) 0x3B,
143            (byte) 0x29, (byte) 0x56, (byte) 0x0C, (byte) 0x00, (byte) 0x1A,
144            (byte) 0x00, (byte) 0x1B, (byte) 0x0A, (byte) 0x00, (byte) 0x19,
145            (byte) 0x00, (byte) 0x1C, (byte) 0x01, (byte) 0x00, (byte) 0x04,
146            (byte) 0x61, (byte) 0x72, (byte) 0x67, (byte) 0x73, (byte) 0x01,
147            (byte) 0x00, (byte) 0x13, (byte) 0x5B, (byte) 0x4C, (byte) 0x6A,
148            (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x2F, (byte) 0x6C,
149            (byte) 0x61, (byte) 0x6E, (byte) 0x67, (byte) 0x2F, (byte) 0x53,
150            (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6E, (byte) 0x67,
151            (byte) 0x3B, (byte) 0x01, (byte) 0x00, (byte) 0x0A, (byte) 0x53,
152            (byte) 0x6F, (byte) 0x75, (byte) 0x72, (byte) 0x63, (byte) 0x65,
153            (byte) 0x46, (byte) 0x69, (byte) 0x6C, (byte) 0x65, (byte) 0x01,
154            (byte) 0x00, (byte) 0x0C, (byte) 0x48, (byte) 0x69, (byte) 0x57,
155            (byte) 0x6F, (byte) 0x72, (byte) 0x6C, (byte) 0x64, (byte) 0x2E,
156            (byte) 0x6A, (byte) 0x61, (byte) 0x76, (byte) 0x61, (byte) 0x00,
157            (byte) 0x21, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x04,
158            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
159            (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x05,
160            (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x00,
161            (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2F,
162            (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00,
163            (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x2A, (byte) 0xB7,
164            (byte) 0x00, (byte) 0x09, (byte) 0xB1, (byte) 0x00, (byte) 0x00,
165            (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x0A, (byte) 0x00,
166            (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x01,
167            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x14, (byte) 0x00,
168            (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0C,
169            (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
170            (byte) 0x05, (byte) 0x00, (byte) 0x0C, (byte) 0x00, (byte) 0x0D,
171            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x09, (byte) 0x00,
172            (byte) 0x0E, (byte) 0x00, (byte) 0x0F, (byte) 0x00, (byte) 0x01,
173            (byte) 0x00, (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x00,
174            (byte) 0x37, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x01,
175            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x09, (byte) 0xB2,
176            (byte) 0x00, (byte) 0x15, (byte) 0x12, (byte) 0x17, (byte) 0xB6,
177            (byte) 0x00, (byte) 0x1D, (byte) 0xB1, (byte) 0x00, (byte) 0x00,
178            (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x0A, (byte) 0x00,
179            (byte) 0x00, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x02,
180            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x17, (byte) 0x00,
181            (byte) 0x08, (byte) 0x00, (byte) 0x18, (byte) 0x00, (byte) 0x0B,
182            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0C, (byte) 0x00,
183            (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x09,
184            (byte) 0x00, (byte) 0x1E, (byte) 0x00, (byte) 0x1F, (byte) 0x00,
185            (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x20,
186            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00,
187            (byte) 0x21, };
188
189    /**
190     * Tests default ctor
191     */
192    @TestTargetNew(
193        level = TestLevel.COMPLETE,
194        notes = "",
195        method = "SecureClassLoader",
196        args = {}
197    )
198    public void testSecureClassLoader() {
199        new MyClassLoader();
200
201        class TestSecurityManager extends SecurityManager {
202            boolean called;
203            @Override
204            public void checkCreateClassLoader() {
205                called = true;
206                super.checkCreateClassLoader();
207            }
208
209            @Override
210            public void checkPermission(Permission permission) {
211                if (permission instanceof RuntimePermission) {
212                    if (permission.getName().equals("createClassLoader")) {
213                        throw new SecurityException();
214                    }
215                }
216            }
217        }
218
219        TestSecurityManager sm = new TestSecurityManager();
220        try {
221            System.setSecurityManager(sm);
222            new MyClassLoader();
223            fail("expected SecurityException");
224        } catch (SecurityException e) {
225            assertTrue("checkCreateClassLoader was not called", sm.called);
226            // ok
227        } finally {
228            System.setSecurityManager(null);
229        }
230    }
231
232    /**
233     * Tests SecureClassLoader(ClassLoader)
234     */
235    @TestTargetNew(
236        level = TestLevel.COMPLETE,
237        notes = "Verification with null parameter missed",
238        method = "SecureClassLoader",
239        args = {java.lang.ClassLoader.class}
240    )
241    @KnownFailure("Android doesn't allow null parent.")
242    public void testSecureClassLoaderClassLoader() throws Exception {
243        URL[] urls = new URL[] { new URL("http://localhost") };
244        URLClassLoader ucl = URLClassLoader.newInstance(urls);
245        new MyClassLoader(ucl);
246
247        try {
248            new MyClassLoader(null);
249        } catch (Exception e) {
250            fail("unexpected exception: " + e);
251        }
252
253        class TestSecurityManager extends SecurityManager {
254            boolean called;
255            @Override
256            public void checkCreateClassLoader() {
257                called = true;
258                super.checkCreateClassLoader();
259            }
260
261            @Override
262            public void checkPermission(Permission permission) {
263                if (permission instanceof RuntimePermission) {
264                    if (permission.getName().equals("createClassLoader")) {
265                        throw new SecurityException();
266                    }
267                }
268            }
269        }
270
271        TestSecurityManager sm = new TestSecurityManager();
272        try {
273            System.setSecurityManager(sm);
274            new MyClassLoader(ucl);
275            fail("expected SecurityException");
276        } catch (SecurityException e) {
277            // ok
278            assertTrue("checkCreateClassLoader was not called", sm.called);
279
280        } finally {
281            System.setSecurityManager(null);
282        }
283    }
284
285    /**
286     * Tests getPermission
287     */
288    @TestTargetNew(
289        level = TestLevel.SUFFICIENT,
290        notes = "",
291        method = "getPermissions",
292        args = {java.security.CodeSource.class}
293    )
294    public void testGetPermissions() throws Exception {
295        URL url = new URL("http://localhost");
296        CodeSource cs = new CodeSource(url, (Certificate[]) null);
297        MyClassLoader ldr = new MyClassLoader();
298        ldr.getPerms(null);
299        ldr.getPerms(cs);
300    }
301
302//    /**
303//     * Tests defineClass(String, byte[], int, int, CodeSource)
304//     */
305//    @TestTargetNew(
306//        level = TestLevel.NOT_FEASIBLE,
307//        notes = "ClassFormatError, IndexOutOfBoundsException, SecurityException checking missed",
308//        method = "defineClass",
309//        args = {java.lang.String.class, byte[].class, int.class, int.class, java.security.CodeSource.class}
310//    )
311//    public void _testDefineClassStringbyteArrayintintCodeSource() {
312//        MyClassLoader ldr = new MyClassLoader();
313//        Class klass = ldr.define(null, klassData, 0, klassData.length, null);
314//        assertEquals(klass.getName(), klassName);
315//    }
316//
317//    /**
318//     * Tests defineClass(String, ByteBuffer, CodeSource)
319//     */
320//    @TestTargetNew(
321//        level = TestLevel.NOT_FEASIBLE,
322//        notes = "ClassFormatError, SecurityException checking missed",
323//        method = "defineClass",
324//        args = {java.lang.String.class, java.nio.ByteBuffer.class, java.security.CodeSource.class}
325//    )
326//    public void _testDefineClassStringByteBufferCodeSource() {
327//        MyClassLoader ldr = new MyClassLoader();
328//        ByteBuffer bbuf = ByteBuffer.wrap(klassData);
329//        Class klass = ldr.define(null, bbuf, null);
330//        assertEquals(klass.getName(), klassName);
331//    }
332
333    class MyClassLoader extends SecureClassLoader {
334
335        public MyClassLoader() {
336            super();
337        }
338
339        public MyClassLoader(ClassLoader parent) {
340            super(parent);
341        }
342
343        public PermissionCollection getPerms(CodeSource codesource) {
344            return super.getPermissions(codesource);
345        }
346
347        public Class define(String name, byte[] bytes) {
348            return defineClass(name, bytes, 0, bytes.length,
349                    (ProtectionDomain) null);
350        }
351
352        public Class define(String name, ByteBuffer b, CodeSource cs) {
353            return defineClass(name, b, cs);
354        }
355
356        public Class define(String name, byte[] b, int off, int len,
357                CodeSource cs) {
358            return defineClass(name, b, off, len, cs);
359        }
360
361    }
362}
363