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