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