1 /*
  2  * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package jdk.internal.access;
 27 
 28 import javax.crypto.SealedObject;
 29 import javax.crypto.spec.SecretKeySpec;
 30 import java.io.ObjectInputFilter;
 31 import java.lang.invoke.MethodHandles;
 32 import java.lang.module.ModuleDescriptor;
 33 import java.security.spec.EncodedKeySpec;
 34 import java.util.ResourceBundle;
 35 import java.util.jar.JarFile;
 36 import java.io.Console;
 37 import java.io.FileDescriptor;
 38 import java.io.FilePermission;
 39 import java.io.ObjectInputStream;
 40 import java.io.PrintStream;
 41 import java.io.PrintWriter;
 42 import java.io.RandomAccessFile;
 43 import java.security.ProtectionDomain;
 44 import java.security.Signature;
 45 
 46 /** A repository of "shared secrets", which are a mechanism for
 47     calling implementation-private methods in another package without
 48     using reflection. A package-private class implements a public
 49     interface and provides the ability to call package-private methods
 50     within that package; the object implementing that interface is
 51     provided through a third package to which access is restricted.
 52     This framework avoids the primary disadvantage of using reflection
 53     for this purpose, namely the loss of compile-time checking. */
 54 
 55 public class SharedSecrets {
 56     private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
 57     private static JavaAWTAccess javaAWTAccess;
 58     private static JavaAWTFontAccess javaAWTFontAccess;
 59     private static JavaBeansAccess javaBeansAccess;
 60     private static JavaLangAccess javaLangAccess;
 61     private static JavaLangInvokeAccess javaLangInvokeAccess;
 62     private static JavaLangModuleAccess javaLangModuleAccess;
 63     private static JavaLangRefAccess javaLangRefAccess;
 64     private static JavaLangReflectAccess javaLangReflectAccess;
 65     private static JavaIOAccess javaIOAccess;
 66     private static JavaIOPrintStreamAccess javaIOPrintStreamAccess;
 67     private static JavaIOPrintWriterAccess javaIOPrintWriterAccess;
 68     private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
 69     private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
 70     private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess;
 71     private static JavaObjectInputStreamReadString javaObjectInputStreamReadString;
 72     private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
 73     private static JavaObjectInputFilterAccess javaObjectInputFilterAccess;
 74     private static JavaNetInetAddressAccess javaNetInetAddressAccess;
 75     private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
 76     private static JavaNetUriAccess javaNetUriAccess;
 77     private static JavaNetURLAccess javaNetURLAccess;
 78     private static JavaNioAccess javaNioAccess;
 79     private static JavaUtilCollectionAccess javaUtilCollectionAccess;
 80     private static JavaUtilJarAccess javaUtilJarAccess;
 81     private static JavaUtilZipFileAccess javaUtilZipFileAccess;
 82     private static JavaUtilResourceBundleAccess javaUtilResourceBundleAccess;
 83     private static JavaSecurityAccess javaSecurityAccess;
 84     private static JavaSecuritySignatureAccess javaSecuritySignatureAccess;
 85     private static JavaSecuritySpecAccess javaSecuritySpecAccess;
 86     private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
 87     private static JavaxCryptoSpecAccess javaxCryptoSpecAccess;
 88 
 89     public static void setJavaUtilCollectionAccess(JavaUtilCollectionAccess juca) {
 90         javaUtilCollectionAccess = juca;
 91     }
 92 
 93     public static JavaUtilCollectionAccess getJavaUtilCollectionAccess() {
 94         var access = javaUtilCollectionAccess;
 95         if (access == null) {
 96             try {
 97                 Class.forName("java.util.ImmutableCollections$Access", true, null);
 98                 access = javaUtilCollectionAccess;
 99             } catch (ClassNotFoundException e) {}
100         }
101         return access;
102     }
103 
104     public static JavaUtilJarAccess javaUtilJarAccess() {
105         var access = javaUtilJarAccess;
106         if (access == null) {
107             // Ensure JarFile is initialized; we know that this class
108             // provides the shared secret
109             ensureClassInitialized(JarFile.class);
110             access = javaUtilJarAccess;
111         }
112         return access;
113     }
114 
115     public static void setJavaUtilJarAccess(JavaUtilJarAccess access) {
116         javaUtilJarAccess = access;
117     }
118 
119     public static void setJavaLangAccess(JavaLangAccess jla) {
120         javaLangAccess = jla;
121     }
122 
123     public static JavaLangAccess getJavaLangAccess() {
124         return javaLangAccess;
125     }
126 
127     public static void setJavaLangInvokeAccess(JavaLangInvokeAccess jlia) {
128         javaLangInvokeAccess = jlia;
129     }
130 
131     public static JavaLangInvokeAccess getJavaLangInvokeAccess() {
132         var access = javaLangInvokeAccess;
133         if (access == null) {
134             try {
135                 Class.forName("java.lang.invoke.MethodHandleImpl", true, null);
136                 access = javaLangInvokeAccess;
137             } catch (ClassNotFoundException e) {}
138         }
139         return access;
140     }
141 
142     public static void setJavaLangModuleAccess(JavaLangModuleAccess jlrma) {
143         javaLangModuleAccess = jlrma;
144     }
145 
146     public static JavaLangModuleAccess getJavaLangModuleAccess() {
147         var access = javaLangModuleAccess;
148         if (access == null) {
149             ensureClassInitialized(ModuleDescriptor.class);
150             access = javaLangModuleAccess;
151         }
152         return access;
153     }
154 
155     public static void setJavaLangRefAccess(JavaLangRefAccess jlra) {
156         javaLangRefAccess = jlra;
157     }
158 
159     public static JavaLangRefAccess getJavaLangRefAccess() {
160         return javaLangRefAccess;
161     }
162 
163     public static void setJavaLangReflectAccess(JavaLangReflectAccess jlra) {
164         javaLangReflectAccess = jlra;
165     }
166 
167     public static JavaLangReflectAccess getJavaLangReflectAccess() {
168         return javaLangReflectAccess;
169     }
170 
171     public static void setJavaNetUriAccess(JavaNetUriAccess jnua) {
172         javaNetUriAccess = jnua;
173     }
174 
175     public static JavaNetUriAccess getJavaNetUriAccess() {
176         var access = javaNetUriAccess;
177         if (access == null) {
178             ensureClassInitialized(java.net.URI.class);
179             access = javaNetUriAccess;
180         }
181         return access;
182     }
183 
184     public static void setJavaNetURLAccess(JavaNetURLAccess jnua) {
185         javaNetURLAccess = jnua;
186     }
187 
188     public static JavaNetURLAccess getJavaNetURLAccess() {
189         var access = javaNetURLAccess;
190         if (access == null) {
191             ensureClassInitialized(java.net.URL.class);
192             access = javaNetURLAccess;
193         }
194         return access;
195     }
196 
197     public static void setJavaNetInetAddressAccess(JavaNetInetAddressAccess jna) {
198         javaNetInetAddressAccess = jna;
199     }
200 
201     public static JavaNetInetAddressAccess getJavaNetInetAddressAccess() {
202         var access = javaNetInetAddressAccess;
203         if (access == null) {
204             ensureClassInitialized(java.net.InetAddress.class);
205             access = javaNetInetAddressAccess;
206         }
207         return access;
208     }
209 
210     public static void setJavaNetHttpCookieAccess(JavaNetHttpCookieAccess a) {
211         javaNetHttpCookieAccess = a;
212     }
213 
214     public static JavaNetHttpCookieAccess getJavaNetHttpCookieAccess() {
215         var access = javaNetHttpCookieAccess;
216         if (access == null) {
217             ensureClassInitialized(java.net.HttpCookie.class);
218             access = javaNetHttpCookieAccess;
219         }
220         return access;
221     }
222 
223     public static void setJavaNioAccess(JavaNioAccess jna) {
224         javaNioAccess = jna;
225     }
226 
227     public static JavaNioAccess getJavaNioAccess() {
228         var access = javaNioAccess;
229         if (access == null) {
230             // Ensure java.nio.Buffer is initialized, which provides the
231             // shared secret.
232             ensureClassInitialized(java.nio.Buffer.class);
233             access = javaNioAccess;
234         }
235         return access;
236     }
237 
238     public static void setJavaIOAccess(JavaIOAccess jia) {
239         javaIOAccess = jia;
240     }
241 
242     public static JavaIOAccess getJavaIOAccess() {
243         var access = javaIOAccess;
244         if (access == null) {
245             ensureClassInitialized(Console.class);
246             access = javaIOAccess;
247         }
248         return access;
249     }
250 
251     public static void setJavaIOCPrintWriterAccess(JavaIOPrintWriterAccess a) {
252         javaIOPrintWriterAccess = a;
253     }
254 
255     public static JavaIOPrintWriterAccess getJavaIOPrintWriterAccess() {
256         var access = javaIOPrintWriterAccess;
257         if (access == null) {
258             ensureClassInitialized(PrintWriter.class);
259             access = javaIOPrintWriterAccess;
260         }
261         return access;
262     }
263 
264     public static void setJavaIOCPrintStreamAccess(JavaIOPrintStreamAccess a) {
265         javaIOPrintStreamAccess = a;
266     }
267 
268     public static JavaIOPrintStreamAccess getJavaIOPrintStreamAccess() {
269         var access = javaIOPrintStreamAccess;
270         if (access == null) {
271             ensureClassInitialized(PrintStream.class);
272             access = javaIOPrintStreamAccess;
273         }
274         return access;
275     }
276 
277     public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
278         javaIOFileDescriptorAccess = jiofda;
279     }
280 
281     public static JavaIOFilePermissionAccess getJavaIOFilePermissionAccess() {
282         var access = javaIOFilePermissionAccess;
283         if (access == null) {
284             ensureClassInitialized(FilePermission.class);
285             access = javaIOFilePermissionAccess;
286         }
287         return access;
288     }
289 
290     public static void setJavaIOFilePermissionAccess(JavaIOFilePermissionAccess jiofpa) {
291         javaIOFilePermissionAccess = jiofpa;
292     }
293 
294     public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
295         var access = javaIOFileDescriptorAccess;
296         if (access == null) {
297             ensureClassInitialized(FileDescriptor.class);
298             access = javaIOFileDescriptorAccess;
299         }
300         return access;
301     }
302 
303     public static void setJavaSecurityAccess(JavaSecurityAccess jsa) {
304         javaSecurityAccess = jsa;
305     }
306 
307     public static JavaSecurityAccess getJavaSecurityAccess() {
308         var access = javaSecurityAccess;
309         if (access == null) {
310             ensureClassInitialized(ProtectionDomain.class);
311             access = javaSecurityAccess;
312         }
313         return access;
314     }
315 
316     public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() {
317         var access = javaUtilZipFileAccess;
318         if (access == null) {
319             ensureClassInitialized(java.util.zip.ZipFile.class);
320             access = javaUtilZipFileAccess;
321         }
322         return access;
323     }
324 
325     public static void setJavaUtilZipFileAccess(JavaUtilZipFileAccess access) {
326         javaUtilZipFileAccess = access;
327     }
328 
329     public static void setJavaAWTAccess(JavaAWTAccess jaa) {
330         javaAWTAccess = jaa;
331     }
332 
333     public static JavaAWTAccess getJavaAWTAccess() {
334         // this may return null in which case calling code needs to
335         // provision for.
336         return javaAWTAccess;
337     }
338 
339     public static void setJavaAWTFontAccess(JavaAWTFontAccess jafa) {
340         javaAWTFontAccess = jafa;
341     }
342 
343     public static JavaAWTFontAccess getJavaAWTFontAccess() {
344         // this may return null in which case calling code needs to
345         // provision for.
346         return javaAWTFontAccess;
347     }
348 
349     public static JavaBeansAccess getJavaBeansAccess() {
350         return javaBeansAccess;
351     }
352 
353     public static void setJavaBeansAccess(JavaBeansAccess access) {
354         javaBeansAccess = access;
355     }
356 
357     public static JavaUtilResourceBundleAccess getJavaUtilResourceBundleAccess() {
358         var access = javaUtilResourceBundleAccess;
359         if (access == null) {
360             ensureClassInitialized(ResourceBundle.class);
361             access = javaUtilResourceBundleAccess;
362         }
363         return access;
364     }
365 
366     public static void setJavaUtilResourceBundleAccess(JavaUtilResourceBundleAccess access) {
367         javaUtilResourceBundleAccess = access;
368     }
369 
370     public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() {
371         var access = javaObjectInputStreamReadString;
372         if (access == null) {
373             ensureClassInitialized(ObjectInputStream.class);
374             access = javaObjectInputStreamReadString;
375         }
376         return access;
377     }
378 
379     public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadString access) {
380         javaObjectInputStreamReadString = access;
381     }
382 
383     public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
384         var access = javaObjectInputStreamAccess;
385         if (access == null) {
386             ensureClassInitialized(ObjectInputStream.class);
387             access = javaObjectInputStreamAccess;
388         }
389         return access;
390     }
391 
392     public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) {
393         javaObjectInputStreamAccess = access;
394     }
395 
396     public static JavaObjectInputFilterAccess getJavaObjectInputFilterAccess() {
397         var access = javaObjectInputFilterAccess;
398         if (access == null) {
399             ensureClassInitialized(ObjectInputFilter.Config.class);
400             access = javaObjectInputFilterAccess;
401         }
402         return access;
403     }
404 
405     public static void setJavaObjectInputFilterAccess(JavaObjectInputFilterAccess access) {
406         javaObjectInputFilterAccess = access;
407     }
408 
409     public static void setJavaIORandomAccessFileAccess(JavaIORandomAccessFileAccess jirafa) {
410         javaIORandomAccessFileAccess = jirafa;
411     }
412 
413     public static JavaIORandomAccessFileAccess getJavaIORandomAccessFileAccess() {
414         var access = javaIORandomAccessFileAccess;
415         if (access == null) {
416             ensureClassInitialized(RandomAccessFile.class);
417             access = javaIORandomAccessFileAccess;
418         }
419         return access;
420     }
421 
422     public static void setJavaSecuritySignatureAccess(JavaSecuritySignatureAccess jssa) {
423         javaSecuritySignatureAccess = jssa;
424     }
425 
426     public static JavaSecuritySignatureAccess getJavaSecuritySignatureAccess() {
427         var access = javaSecuritySignatureAccess;
428         if (access == null) {
429             ensureClassInitialized(Signature.class);
430             access = javaSecuritySignatureAccess;
431         }
432         return access;
433     }
434 
435     public static void setJavaSecuritySpecAccess(JavaSecuritySpecAccess jssa) {
436         javaSecuritySpecAccess = jssa;
437     }
438 
439     public static JavaSecuritySpecAccess getJavaSecuritySpecAccess() {
440         if (javaSecuritySpecAccess == null) {
441             ensureClassInitialized(EncodedKeySpec.class);
442         }
443         return javaSecuritySpecAccess;
444     }
445 
446     public static void setJavaxCryptoSpecAccess(JavaxCryptoSpecAccess jcsa) {
447         javaxCryptoSpecAccess = jcsa;
448     }
449 
450     public static JavaxCryptoSpecAccess getJavaxCryptoSpecAccess() {
451         if (javaxCryptoSpecAccess == null) {
452             ensureClassInitialized(SecretKeySpec.class);
453         }
454         return javaxCryptoSpecAccess;
455     }
456 
457     public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) {
458         javaxCryptoSealedObjectAccess = jcsoa;
459     }
460 
461     public static JavaxCryptoSealedObjectAccess getJavaxCryptoSealedObjectAccess() {
462         var access = javaxCryptoSealedObjectAccess;
463         if (access == null) {
464             ensureClassInitialized(SealedObject.class);
465             access = javaxCryptoSealedObjectAccess;
466         }
467         return access;
468     }
469 
470     private static void ensureClassInitialized(Class<?> c) {
471         try {
472             MethodHandles.lookup().ensureInitialized(c);
473         } catch (IllegalAccessException e) {}
474     }
475 }