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 package jdk.internal.access; 26 27 import jdk.internal.misc.Unsafe; 28 import java.io.ObjectInputStream; 29 import java.io.FileDescriptor; 30 /** A repository of "shared secrets", which are a mechanism for 31 calling implementation-private methods in another package without 32 using reflection. A package-private class implements a public 33 interface and provides the ability to call package-private methods 34 within that package; the object implementing that interface is 35 provided through a third package to which access is restricted. 36 This framework avoids the primary disadvantage of using reflection 37 for this purpose, namely the loss of compile-time checking. */ 38 public class SharedSecrets { 39 // Android-changed: use Unsafe instead of MethodHandles. 40 // private static final MethodHandles.Lookup lookup = MethodHandles.lookup(); 41 private static final Unsafe unsafe = Unsafe.getUnsafe(); 42 // BEGIN Android-removed: Pruned unused access interfaces. 43 /* 44 private static JavaAWTAccess javaAWTAccess; 45 private static JavaAWTFontAccess javaAWTFontAccess; 46 private static JavaBeansAccess javaBeansAccess; 47 */ 48 // END Android-removed: Pruned unused access interfaces. 49 private static final JavaLangAccess javaLangAccess = new JavaLangAccess(); 50 // BEGIN Android-removed: Pruned unused access interfaces. 51 /* 52 private static JavaLangInvokeAccess javaLangInvokeAccess; 53 private static JavaLangModuleAccess javaLangModuleAccess; 54 private static JavaLangRefAccess javaLangRefAccess; 55 private static JavaLangReflectAccess javaLangReflectAccess; 56 private static JavaIOAccess javaIOAccess; 57 */ 58 // END Android-removed: Pruned unused access interfaces. 59 private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess; 60 // BEGIN Android-removed: Pruned unused access interfaces. 61 /* 62 private static JavaIOFilePermissionAccess javaIOFilePermissionAccess; 63 private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess; 64 private static JavaObjectInputStreamReadString javaObjectInputStreamReadString; 65 */ 66 // END Android-removed: Pruned unused access interfaces. 67 private static JavaObjectInputStreamAccess javaObjectInputStreamAccess; 68 // BEGIN Android-removed: Pruned unused access interfaces. 69 /* 70 private static JavaObjectInputFilterAccess javaObjectInputFilterAccess; 71 private static JavaNetInetAddressAccess javaNetInetAddressAccess; 72 private static JavaNetHttpCookieAccess javaNetHttpCookieAccess; 73 private static JavaNetUriAccess javaNetUriAccess; 74 private static JavaNetURLAccess javaNetURLAccess; 75 private static JavaNioAccess javaNioAccess; 76 */ 77 // END Android-removed: Pruned unused access interfaces. 78 private static JavaUtilCollectionAccess javaUtilCollectionAccess; 79 // BEGIN Android-removed: Pruned unused access interfaces. 80 /* 81 private static JavaUtilJarAccess javaUtilJarAccess; 82 private static JavaUtilZipFileAccess javaUtilZipFileAccess; 83 private static JavaUtilResourceBundleAccess javaUtilResourceBundleAccess; 84 private static JavaSecurityAccess javaSecurityAccess; 85 private static JavaSecuritySignatureAccess javaSecuritySignatureAccess; 86 private static JavaSecuritySpecAccess javaSecuritySpecAccess; 87 private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess; 88 private static JavaxCryptoSpecAccess javaxCryptoSpecAccess; 89 */ 90 // END Android-removed: Pruned unused access interfaces. setJavaUtilCollectionAccess(JavaUtilCollectionAccess juca)91 public static void setJavaUtilCollectionAccess(JavaUtilCollectionAccess juca) { 92 javaUtilCollectionAccess = juca; 93 } getJavaUtilCollectionAccess()94 public static JavaUtilCollectionAccess getJavaUtilCollectionAccess() { 95 var access = javaUtilCollectionAccess; 96 if (access == null) { 97 try { 98 Class.forName("java.util.ImmutableCollections$Access", true, null); 99 access = javaUtilCollectionAccess; 100 } catch (ClassNotFoundException e) {} 101 } 102 return access; 103 } 104 // BEGIN Android-removed: Pruned unused access interfaces. 105 /* 106 public static JavaUtilJarAccess javaUtilJarAccess() { 107 var access = javaUtilJarAccess; 108 if (access == null) { 109 // Ensure JarFile is initialized; we know that this class 110 // provides the shared secret 111 ensureClassInitialized(JarFile.class); 112 access = javaUtilJarAccess; 113 } 114 return access; 115 } 116 public static void setJavaUtilJarAccess(JavaUtilJarAccess access) { 117 javaUtilJarAccess = access; 118 } 119 public static void setJavaLangAccess(JavaLangAccess jla) { 120 javaLangAccess = jla; 121 } 122 */ 123 // END Android-removed: Pruned unused access interfaces. getJavaLangAccess()124 public static JavaLangAccess getJavaLangAccess() { 125 return javaLangAccess; 126 } 127 // BEGIN Android-removed: Pruned unused access interfaces. 128 /* 129 public static void setJavaLangInvokeAccess(JavaLangInvokeAccess jlia) { 130 javaLangInvokeAccess = jlia; 131 } 132 public static JavaLangInvokeAccess getJavaLangInvokeAccess() { 133 var access = javaLangInvokeAccess; 134 if (access == null) { 135 try { 136 Class.forName("java.lang.invoke.MethodHandleImpl", true, null); 137 access = javaLangInvokeAccess; 138 } catch (ClassNotFoundException e) {} 139 } 140 return access; 141 } 142 public static void setJavaLangModuleAccess(JavaLangModuleAccess jlrma) { 143 javaLangModuleAccess = jlrma; 144 } 145 public static JavaLangModuleAccess getJavaLangModuleAccess() { 146 var access = javaLangModuleAccess; 147 if (access == null) { 148 ensureClassInitialized(ModuleDescriptor.class); 149 access = javaLangModuleAccess; 150 } 151 return access; 152 } 153 public static void setJavaLangRefAccess(JavaLangRefAccess jlra) { 154 javaLangRefAccess = jlra; 155 } 156 public static JavaLangRefAccess getJavaLangRefAccess() { 157 return javaLangRefAccess; 158 } 159 public static void setJavaLangReflectAccess(JavaLangReflectAccess jlra) { 160 javaLangReflectAccess = jlra; 161 } 162 public static JavaLangReflectAccess getJavaLangReflectAccess() { 163 return javaLangReflectAccess; 164 } 165 public static void setJavaNetUriAccess(JavaNetUriAccess jnua) { 166 javaNetUriAccess = jnua; 167 } 168 public static JavaNetUriAccess getJavaNetUriAccess() { 169 var access = javaNetUriAccess; 170 if (access == null) { 171 ensureClassInitialized(java.net.URI.class); 172 access = javaNetUriAccess; 173 } 174 return access; 175 } 176 public static void setJavaNetURLAccess(JavaNetURLAccess jnua) { 177 javaNetURLAccess = jnua; 178 } 179 public static JavaNetURLAccess getJavaNetURLAccess() { 180 var access = javaNetURLAccess; 181 if (access == null) { 182 ensureClassInitialized(java.net.URL.class); 183 access = javaNetURLAccess; 184 } 185 return access; 186 } 187 public static void setJavaNetInetAddressAccess(JavaNetInetAddressAccess jna) { 188 javaNetInetAddressAccess = jna; 189 } 190 public static JavaNetInetAddressAccess getJavaNetInetAddressAccess() { 191 var access = javaNetInetAddressAccess; 192 if (access == null) { 193 ensureClassInitialized(java.net.InetAddress.class); 194 access = javaNetInetAddressAccess; 195 } 196 return access; 197 } 198 public static void setJavaNetHttpCookieAccess(JavaNetHttpCookieAccess a) { 199 javaNetHttpCookieAccess = a; 200 } 201 public static JavaNetHttpCookieAccess getJavaNetHttpCookieAccess() { 202 var access = javaNetHttpCookieAccess; 203 if (access == null) { 204 ensureClassInitialized(java.net.HttpCookie.class); 205 access = javaNetHttpCookieAccess; 206 } 207 return access; 208 } 209 public static void setJavaNioAccess(JavaNioAccess jna) { 210 javaNioAccess = jna; 211 } 212 public static JavaNioAccess getJavaNioAccess() { 213 var access = javaNioAccess; 214 if (access == null) { 215 // Ensure java.nio.Buffer is initialized, which provides the 216 // shared secret. 217 ensureClassInitialized(java.nio.Buffer.class); 218 access = javaNioAccess; 219 } 220 return access; 221 } 222 public static void setJavaIOAccess(JavaIOAccess jia) { 223 javaIOAccess = jia; 224 } 225 public static JavaIOAccess getJavaIOAccess() { 226 var access = javaIOAccess; 227 if (access == null) { 228 ensureClassInitialized(Console.class); 229 access = javaIOAccess; 230 } 231 return access; 232 } 233 */ 234 // END Android-removed: Pruned unused access interfaces. setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda)235 public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) { 236 javaIOFileDescriptorAccess = jiofda; 237 } 238 // BEGIN Android-removed: Pruned unused access interfaces. 239 /* 240 public static JavaIOFilePermissionAccess getJavaIOFilePermissionAccess() { 241 var access = javaIOFilePermissionAccess; 242 if (access == null) { 243 ensureClassInitialized(FilePermission.class); 244 access = javaIOFilePermissionAccess; 245 } 246 return access; 247 } 248 public static void setJavaIOFilePermissionAccess(JavaIOFilePermissionAccess jiofpa) { 249 javaIOFilePermissionAccess = jiofpa; 250 } 251 */ 252 // END Android-removed: Pruned unused access interfaces. getJavaIOFileDescriptorAccess()253 public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() { 254 var access = javaIOFileDescriptorAccess; 255 if (access == null) { 256 ensureClassInitialized(FileDescriptor.class); 257 access = javaIOFileDescriptorAccess; 258 } 259 return access; 260 } 261 // BEGIN Android-removed: Pruned unused access interfaces. 262 /* 263 public static void setJavaSecurityAccess(JavaSecurityAccess jsa) { 264 javaSecurityAccess = jsa; 265 } 266 public static JavaSecurityAccess getJavaSecurityAccess() { 267 var access = javaSecurityAccess; 268 if (access == null) { 269 ensureClassInitialized(ProtectionDomain.class); 270 access = javaSecurityAccess; 271 } 272 return access; 273 } 274 public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() { 275 var access = javaUtilZipFileAccess; 276 if (access == null) { 277 ensureClassInitialized(java.util.zip.ZipFile.class); 278 access = javaUtilZipFileAccess; 279 } 280 return access; 281 } 282 public static void setJavaUtilZipFileAccess(JavaUtilZipFileAccess access) { 283 javaUtilZipFileAccess = access; 284 } 285 public static void setJavaAWTAccess(JavaAWTAccess jaa) { 286 javaAWTAccess = jaa; 287 } 288 public static JavaAWTAccess getJavaAWTAccess() { 289 // this may return null in which case calling code needs to 290 // provision for. 291 return javaAWTAccess; 292 } 293 public static void setJavaAWTFontAccess(JavaAWTFontAccess jafa) { 294 javaAWTFontAccess = jafa; 295 } 296 public static JavaAWTFontAccess getJavaAWTFontAccess() { 297 // this may return null in which case calling code needs to 298 // provision for. 299 return javaAWTFontAccess; 300 } 301 public static JavaBeansAccess getJavaBeansAccess() { 302 return javaBeansAccess; 303 } 304 public static void setJavaBeansAccess(JavaBeansAccess access) { 305 javaBeansAccess = access; 306 } 307 public static JavaUtilResourceBundleAccess getJavaUtilResourceBundleAccess() { 308 var access = javaUtilResourceBundleAccess; 309 if (access == null) { 310 ensureClassInitialized(ResourceBundle.class); 311 access = javaUtilResourceBundleAccess; 312 } 313 return access; 314 } 315 public static void setJavaUtilResourceBundleAccess(JavaUtilResourceBundleAccess access) { 316 javaUtilResourceBundleAccess = access; 317 } 318 public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() { 319 var access = javaObjectInputStreamReadString; 320 if (access == null) { 321 ensureClassInitialized(ObjectInputStream.class); 322 access = javaObjectInputStreamReadString; 323 } 324 return access; 325 } 326 public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadString access) { 327 javaObjectInputStreamReadString = access; 328 } 329 */ 330 // END Android-removed: Pruned unused access interfaces. getJavaObjectInputStreamAccess()331 public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() { 332 var access = javaObjectInputStreamAccess; 333 if (access == null) { 334 ensureClassInitialized(ObjectInputStream.class); 335 access = javaObjectInputStreamAccess; 336 } 337 return access; 338 } setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access)339 public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) { 340 javaObjectInputStreamAccess = access; 341 } 342 // BEGIN Android-removed: Pruned unused access interfaces. 343 /* 344 public static JavaObjectInputFilterAccess getJavaObjectInputFilterAccess() { 345 var access = javaObjectInputFilterAccess; 346 if (access == null) { 347 ensureClassInitialized(ObjectInputFilter.Config.class); 348 access = javaObjectInputFilterAccess; 349 } 350 return access; 351 } 352 public static void setJavaObjectInputFilterAccess(JavaObjectInputFilterAccess access) { 353 javaObjectInputFilterAccess = access; 354 } 355 public static void setJavaIORandomAccessFileAccess(JavaIORandomAccessFileAccess jirafa) { 356 javaIORandomAccessFileAccess = jirafa; 357 } 358 public static JavaIORandomAccessFileAccess getJavaIORandomAccessFileAccess() { 359 var access = javaIORandomAccessFileAccess; 360 if (access == null) { 361 ensureClassInitialized(RandomAccessFile.class); 362 access = javaIORandomAccessFileAccess; 363 } 364 return access; 365 } 366 public static void setJavaSecuritySignatureAccess(JavaSecuritySignatureAccess jssa) { 367 javaSecuritySignatureAccess = jssa; 368 } 369 public static JavaSecuritySignatureAccess getJavaSecuritySignatureAccess() { 370 var access = javaSecuritySignatureAccess; 371 if (access == null) { 372 ensureClassInitialized(Signature.class); 373 access = javaSecuritySignatureAccess; 374 } 375 return access; 376 } 377 public static void setJavaSecuritySpecAccess(JavaSecuritySpecAccess jssa) { 378 javaSecuritySpecAccess = jssa; 379 } 380 public static JavaSecuritySpecAccess getJavaSecuritySpecAccess() { 381 if (javaSecuritySpecAccess == null) { 382 ensureClassInitialized(EncodedKeySpec.class); 383 } 384 return javaSecuritySpecAccess; 385 } 386 public static void setJavaxCryptoSpecAccess(JavaxCryptoSpecAccess jcsa) { 387 javaxCryptoSpecAccess = jcsa; 388 } 389 public static JavaxCryptoSpecAccess getJavaxCryptoSpecAccess() { 390 if (javaxCryptoSpecAccess == null) { 391 ensureClassInitialized(SecretKeySpec.class); 392 } 393 return javaxCryptoSpecAccess; 394 } 395 public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) { 396 javaxCryptoSealedObjectAccess = jcsoa; 397 } 398 public static JavaxCryptoSealedObjectAccess getJavaxCryptoSealedObjectAccess() { 399 var access = javaxCryptoSealedObjectAccess; 400 if (access == null) { 401 ensureClassInitialized(SealedObject.class); 402 access = javaxCryptoSealedObjectAccess; 403 } 404 return access; 405 } 406 */ 407 // END Android-removed: Pruned unused access interfaces. ensureClassInitialized(Class<?> c)408 private static void ensureClassInitialized(Class<?> c) { 409 // Android-changed: MH.Lookup.ensureInitialized is not yet available, use Unsafe. 410 /* 411 try { 412 MethodHandles.lookup().ensureInitialized(c); 413 } catch (IllegalAccessException e) {} 414 */ 415 unsafe.ensureClassInitialized(c); 416 } 417 } 418