History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/jca (23 of 18352 files). Show all

Unified · Split

23 files
  1. java/pkg/sun/security/jca/GetInstance$1.class +0 −0
  2. java/pkg/sun/security/jca/GetInstance$Instance.class +0 −0
  3. java/pkg/sun/security/jca/GetInstance.class +0 −0
  4. java/pkg/sun/security/jca/GetInstance.java +264 −0
  5. java/pkg/sun/security/jca/JCAUtil.class +0 −0
  6. java/pkg/sun/security/jca/JCAUtil.java +85 −0
  7. java/pkg/sun/security/jca/ProviderConfig$1.class +0 −0
  8. java/pkg/sun/security/jca/ProviderConfig$2.class +0 −0
  9. java/pkg/sun/security/jca/ProviderConfig$3.class +0 −0
  10. java/pkg/sun/security/jca/ProviderConfig.class +0 −0
  11. java/pkg/sun/security/jca/ProviderConfig.java +284 −0
  12. java/pkg/sun/security/jca/ProviderList$1.class +0 −0
  13. java/pkg/sun/security/jca/ProviderList$2.class +0 −0
  14. java/pkg/sun/security/jca/ProviderList$3.class +0 −0
  15. java/pkg/sun/security/jca/ProviderList$ServiceList$1.class +0 −0
  16. java/pkg/sun/security/jca/ProviderList$ServiceList.class +0 −0
  17. java/pkg/sun/security/jca/ProviderList.class +0 −0
  18. java/pkg/sun/security/jca/ProviderList.java +504 −0
  19. java/pkg/sun/security/jca/Providers.class +0 −0
  20. java/pkg/sun/security/jca/Providers.java +250 −0
  21. java/pkg/sun/security/jca/ServiceId.class +0 −0
  22. java/pkg/sun/security/jca/ServiceId.java +45 −0
  23. java/pkg/sun/security/jca/mkfile +13 −0
java/pkg/sun/security/jca/GetInstance$1.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/GetInstance$Instance.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/GetInstance.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/GetInstance.java+264−0
@@ -0,0 +1,264 @@
1/*
2 * Copyright (c) 2003, 2006, 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
26package sun.security.jca;
27
28import java.util.*;
29
30import java.security.*;
31import java.security.Provider.Service;
32
33/**
34 * Collection of utility methods to facilitate implementing getInstance()
35 * methods in the JCA/JCE/JSSE/... framework.
36 *
37 * @author Andreas Sterbenz
38 * @since 1.5
39 */
40public class GetInstance {
41
42 private GetInstance() {
43 // empty
44 }
45
46 /**
47 * Static inner class representing a newly created instance.
48 */
49 public static final class Instance {
50 // public final fields, access directly without accessors
51 public final Provider provider;
52 public final Object impl;
53 private Instance(Provider provider, Object impl) {
54 this.provider = provider;
55 this.impl = impl;
56 }
57 // Return Provider and implementation as an array as used in the
58 // old Security.getImpl() methods.
59 public Object[] toArray() {
60 return new Object[] {impl, provider};
61 }
62 }
63
64 public static Service getService(String type, String algorithm)
65 throws NoSuchAlgorithmException {
66 ProviderList list = Providers.getProviderList();
67 Service s = list.getService(type, algorithm);
68 if (s == null) {
69 throw new NoSuchAlgorithmException
70 (algorithm + " " + type + " not available");
71 }
72 return s;
73 }
74
75 public static Service getService(String type, String algorithm,
76 String provider) throws NoSuchAlgorithmException,
77 NoSuchProviderException {
78 if ((provider == null) || (provider.length() == 0)) {
79 throw new IllegalArgumentException("missing provider");
80 }
81 Provider p = Providers.getProviderList().getProvider(provider);
82 if (p == null) {
83 throw new NoSuchProviderException("no such provider: " + provider);
84 }
85 Service s = p.getService(type, algorithm);
86 if (s == null) {
87 throw new NoSuchAlgorithmException("no such algorithm: "
88 + algorithm + " for provider " + provider);
89 }
90 return s;
91 }
92
93 public static Service getService(String type, String algorithm,
94 Provider provider) throws NoSuchAlgorithmException {
95 if (provider == null) {
96 throw new IllegalArgumentException("missing provider");
97 }
98 Service s = provider.getService(type, algorithm);
99 if (s == null) {
100 throw new NoSuchAlgorithmException("no such algorithm: "
101 + algorithm + " for provider " + provider.getName());
102 }
103 return s;
104 }
105
106 /**
107 * Return a List of all the available Services that implement
108 * (type, algorithm). Note that the list is initialized lazily
109 * and Provider loading and lookup is only trigered when
110 * necessary.
111 */
112 public static List<Service> getServices(String type, String algorithm) {
113 ProviderList list = Providers.getProviderList();
114 return list.getServices(type, algorithm);
115 }
116
117 /**
118 * This method exists for compatibility with JCE only. It will be removed
119 * once JCE has been changed to use the replacement method.
120 * @deprecated use getServices(List<ServiceId>) instead
121 */
122 @Deprecated
123 public static List<Service> getServices(String type,
124 List<String> algorithms) {
125 ProviderList list = Providers.getProviderList();
126 return list.getServices(type, algorithms);
127 }
128
129 /**
130 * Return a List of all the available Services that implement any of
131 * the specified algorithms. See getServices(String, String) for detals.
132 */
133 public static List<Service> getServices(List<ServiceId> ids) {
134 ProviderList list = Providers.getProviderList();
135 return list.getServices(ids);
136 }
137
138 /*
139 * For all the getInstance() methods below:
140 * @param type the type of engine (e.g. MessageDigest)
141 * @param clazz the Spi class that the implementation must subclass
142 * (e.g. MessageDigestSpi.class) or null if no superclass check
143 * is required
144 * @param algorithm the name of the algorithm (or alias), e.g. MD5
145 * @param provider the provider (String or Provider object)
146 * @param param the parameter to pass to the Spi constructor
147 * (for CertStores)
148 *
149 * There are overloaded methods for all the permutations.
150 */
151
152 public static Instance getInstance(String type, Class clazz,
153 String algorithm) throws NoSuchAlgorithmException {
154 // in the almost all cases, the first service will work
155 // avoid taking long path if so
156 ProviderList list = Providers.getProviderList();
157 Service firstService = list.getService(type, algorithm);
158 if (firstService == null) {
159 throw new NoSuchAlgorithmException
160 (algorithm + " " + type + " not available");
161 }
162 NoSuchAlgorithmException failure;
163 try {
164 return getInstance(firstService, clazz);
165 } catch (NoSuchAlgorithmException e) {
166 failure = e;
167 }
168 // if we cannot get the service from the prefered provider,
169 // fail over to the next
170 for (Service s : list.getServices(type, algorithm)) {
171 if (s == firstService) {
172 // do not retry initial failed service
173 continue;
174 }
175 try {
176 return getInstance(s, clazz);
177 } catch (NoSuchAlgorithmException e) {
178 failure = e;
179 }
180 }
181 throw failure;
182 }
183
184 public static Instance getInstance(String type, Class clazz,
185 String algorithm, Object param) throws NoSuchAlgorithmException {
186 List<Service> services = getServices(type, algorithm);
187 NoSuchAlgorithmException failure = null;
188 for (Service s : services) {
189 try {
190 return getInstance(s, clazz, param);
191 } catch (NoSuchAlgorithmException e) {
192 failure = e;
193 }
194 }
195 if (failure != null) {
196 throw failure;
197 } else {
198 throw new NoSuchAlgorithmException
199 (algorithm + " " + type + " not available");
200 }
201 }
202
203 public static Instance getInstance(String type, Class clazz,
204 String algorithm, String provider) throws NoSuchAlgorithmException,
205 NoSuchProviderException {
206 return getInstance(getService(type, algorithm, provider), clazz);
207 }
208
209 public static Instance getInstance(String type, Class clazz,
210 String algorithm, Object param, String provider)
211 throws NoSuchAlgorithmException, NoSuchProviderException {
212 return getInstance(getService(type, algorithm, provider), clazz, param);
213 }
214
215 public static Instance getInstance(String type, Class clazz,
216 String algorithm, Provider provider)
217 throws NoSuchAlgorithmException {
218 return getInstance(getService(type, algorithm, provider), clazz);
219 }
220
221 public static Instance getInstance(String type, Class clazz,
222 String algorithm, Object param, Provider provider)
223 throws NoSuchAlgorithmException {
224 return getInstance(getService(type, algorithm, provider), clazz, param);
225 }
226
227 /*
228 * The two getInstance() methods below take a service. They are
229 * intended for classes that cannot use the standard methods, e.g.
230 * because they implement delayed provider selection like the
231 * Signature class.
232 */
233
234 public static Instance getInstance(Service s, Class clazz)
235 throws NoSuchAlgorithmException {
236 Object instance = s.newInstance(null);
237 checkSuperClass(s, instance.getClass(), clazz);
238 return new Instance(s.getProvider(), instance);
239 }
240
241 public static Instance getInstance(Service s, Class clazz,
242 Object param) throws NoSuchAlgorithmException {
243 Object instance = s.newInstance(param);
244 checkSuperClass(s, instance.getClass(), clazz);
245 return new Instance(s.getProvider(), instance);
246 }
247
248 /**
249 * Check is subClass is a subclass of superClass. If not,
250 * throw a NoSuchAlgorithmException.
251 */
252 public static void checkSuperClass(Service s, Class subClass,
253 Class superClass) throws NoSuchAlgorithmException {
254 if (superClass == null) {
255 return;
256 }
257 if (superClass.isAssignableFrom(subClass) == false) {
258 throw new NoSuchAlgorithmException
259 ("class configured for " + s.getType() + ": "
260 + s.getClassName() + " not a " + s.getType());
261 }
262 }
263
264}
java/pkg/sun/security/jca/JCAUtil.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/JCAUtil.java+85−0
@@ -0,0 +1,85 @@
1/*
2 * Copyright (c) 2003, 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
26package sun.security.jca;
27
28import java.lang.ref.*;
29
30import java.security.*;
31
32/**
33 * Collection of static utility methods used by the security framework.
34 *
35 * @author Andreas Sterbenz
36 * @since 1.5
37 */
38public final class JCAUtil {
39
40 private JCAUtil() {
41 // no instantiation
42 }
43
44 // lock to use for synchronization
45 private static final Object LOCK = JCAUtil.class;
46
47 // cached SecureRandom instance
48 private static volatile SecureRandom secureRandom;
49
50 // size of the temporary arrays we use. Should fit into the CPU's 1st
51 // level cache and could be adjusted based on the platform
52 private final static int ARRAY_SIZE = 4096;
53
54 /**
55 * Get the size of a temporary buffer array to use in order to be
56 * cache efficient. totalSize indicates the total amount of data to
57 * be buffered. Used by the engineUpdate(ByteBuffer) methods.
58 */
59 public static int getTempArraySize(int totalSize) {
60 return Math.min(ARRAY_SIZE, totalSize);
61 }
62
63 /**
64 * Get a SecureRandom instance. This method should me used by JDK
65 * internal code in favor of calling "new SecureRandom()". That needs to
66 * iterate through the provider table to find the default SecureRandom
67 * implementation, which is fairly inefficient.
68 */
69 public static SecureRandom getSecureRandom() {
70 // we use double checked locking to minimize synchronization
71 // works because we use a volatile reference
72 SecureRandom r = secureRandom;
73 if (r == null) {
74 synchronized (LOCK) {
75 r = secureRandom;
76 if (r == null) {
77 r = new SecureRandom();
78 secureRandom = r;
79 }
80 }
81 }
82 return r;
83 }
84
85}
java/pkg/sun/security/jca/ProviderConfig$1.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ProviderConfig$2.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ProviderConfig$3.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ProviderConfig.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ProviderConfig.java+284−0
@@ -0,0 +1,284 @@
1/*
2 * Copyright (c) 2003, 2009, 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
26package sun.security.jca;
27
28import java.io.File;
29import java.lang.reflect.*;
30
31import java.security.*;
32
33import sun.security.util.PropertyExpander;
34
35/**
36 * Class representing a configured provider. Encapsulates configuration
37 * (className plus optional argument), the provider loading logic, and
38 * the loaded Provider object itself.
39 *
40 * @author Andreas Sterbenz
41 * @since 1.5
42 */
43final class ProviderConfig {
44
45 private final static sun.security.util.Debug debug =
46 sun.security.util.Debug.getInstance("jca", "ProviderConfig");
47
48 // classname of the SunPKCS11-Solaris provider
49 private static final String P11_SOL_NAME =
50 "sun.security.pkcs11.SunPKCS11";
51
52 // config file argument of the SunPKCS11-Solaris provider
53 private static final String P11_SOL_ARG =
54 "${java.home}/lib/security/sunpkcs11-solaris.cfg";
55
56 // maximum number of times to try loading a provider before giving up
57 private final static int MAX_LOAD_TRIES = 30;
58
59 // parameters for the Provider(String) constructor,
60 // use by doLoadProvider()
61 private final static Class[] CL_STRING = { String.class };
62
63 // name of the provider class
64 private final String className;
65
66 // argument to the provider constructor,
67 // empty string indicates no-arg constructor
68 private final String argument;
69
70 // number of times we have already tried to load this provider
71 private int tries;
72
73 // Provider object, if loaded
74 private volatile Provider provider;
75
76 // flag indicating if we are currently trying to load the provider
77 // used to detect recursion
78 private boolean isLoading;
79
80 ProviderConfig(String className, String argument) {
81 if (className.equals(P11_SOL_NAME) && argument.equals(P11_SOL_ARG)) {
82 checkSunPKCS11Solaris();
83 }
84 this.className = className;
85 this.argument = expand(argument);
86 }
87
88 ProviderConfig(String className) {
89 this(className, "");
90 }
91
92 ProviderConfig(Provider provider) {
93 this.className = provider.getClass().getName();
94 this.argument = "";
95 this.provider = provider;
96 }
97
98 // check if we should try to load the SunPKCS11-Solaris provider
99 // avoid if not available (pre Solaris 10) to reduce startup time
100 // or if disabled via system property
101 private void checkSunPKCS11Solaris() {
102 Boolean o = AccessController.doPrivileged(
103 new PrivilegedAction<Boolean>() {
104 public Boolean run() {
105 File file = new File("/usr/lib/libpkcs11.so");
106 if (file.exists() == false) {
107 return Boolean.FALSE;
108 }
109 if ("false".equalsIgnoreCase(System.getProperty
110 ("sun.security.pkcs11.enable-solaris"))) {
111 return Boolean.FALSE;
112 }
113 return Boolean.TRUE;
114 }
115 });
116 if (o == Boolean.FALSE) {
117 tries = MAX_LOAD_TRIES;
118 }
119 }
120
121 private boolean hasArgument() {
122 return argument.length() != 0;
123 }
124
125 // should we try to load this provider?
126 private boolean shouldLoad() {
127 return (tries < MAX_LOAD_TRIES);
128 }
129
130 // do not try to load this provider again
131 private void disableLoad() {
132 tries = MAX_LOAD_TRIES;
133 }
134
135 boolean isLoaded() {
136 return (provider != null);
137 }
138
139 public boolean equals(Object obj) {
140 if (this == obj) {
141 return true;
142 }
143 if (obj instanceof ProviderConfig == false) {
144 return false;
145 }
146 ProviderConfig other = (ProviderConfig)obj;
147 return this.className.equals(other.className)
148 && this.argument.equals(other.argument);
149 }
150
151 public int hashCode() {
152 return className.hashCode() + argument.hashCode();
153 }
154
155 public String toString() {
156 if (hasArgument()) {
157 return className + "('" + argument + "')";
158 } else {
159 return className;
160 }
161 }
162
163 /**
164 * Get the provider object. Loads the provider if it is not already loaded.
165 */
166 synchronized Provider getProvider() {
167 // volatile variable load
168 Provider p = provider;
169 if (p != null) {
170 return p;
171 }
172 if (shouldLoad() == false) {
173 return null;
174 }
175 if (isLoading) {
176 // because this method is synchronized, this can only
177 // happen if there is recursion.
178 if (debug != null) {
179 debug.println("Recursion loading provider: " + this);
180 new Exception("Call trace").printStackTrace();
181 }
182 return null;
183 }
184 try {
185 isLoading = true;
186 tries++;
187 p = doLoadProvider();
188 } finally {
189 isLoading = false;
190 }
191 provider = p;
192 return p;
193 }
194
195 /**
196 * Load and instantiate the Provider described by this class.
197 *
198 * NOTE use of doPrivileged().
199 *
200 * @return null if the Provider could not be loaded
201 *
202 * @throws ProviderException if executing the Provider's constructor
203 * throws a ProviderException. All other Exceptions are ignored.
204 */
205 private Provider doLoadProvider() {
206 return AccessController.doPrivileged(new PrivilegedAction<Provider>() {
207 public Provider run() {
208 if (debug != null) {
209 debug.println("Loading provider: " + ProviderConfig.this);
210 }
211 try {
212 ClassLoader cl = ClassLoader.getSystemClassLoader();
213 Class<?> provClass;
214 if (cl != null) {
215 provClass = cl.loadClass(className);
216 } else {
217 provClass = Class.forName(className);
218 }
219 Object obj;
220 if (hasArgument() == false) {
221 obj = provClass.newInstance();
222 } else {
223 Constructor<?> cons = provClass.getConstructor(CL_STRING);
224 obj = cons.newInstance(argument);
225 }
226 if (obj instanceof Provider) {
227 if (debug != null) {
228 debug.println("Loaded provider " + obj);
229 }
230 return (Provider)obj;
231 } else {
232 if (debug != null) {
233 debug.println(className + " is not a provider");
234 }
235 disableLoad();
236 return null;
237 }
238 } catch (Exception e) {
239 Throwable t;
240 if (e instanceof InvocationTargetException) {
241 t = ((InvocationTargetException)e).getCause();
242 } else {
243 t = e;
244 }
245 if (debug != null) {
246 debug.println("Error loading provider " + ProviderConfig.this);
247 t.printStackTrace();
248 }
249 // provider indicates fatal error, pass through exception
250 if (t instanceof ProviderException) {
251 throw (ProviderException)t;
252 }
253 // provider indicates that loading should not be retried
254 if (t instanceof UnsupportedOperationException) {
255 disableLoad();
256 }
257 return null;
258 }
259 }
260 });
261 }
262
263 /**
264 * Perform property expansion of the provider value.
265 *
266 * NOTE use of doPrivileged().
267 */
268 private static String expand(final String value) {
269 // shortcut if value does not contain any properties
270 if (value.contains("${") == false) {
271 return value;
272 }
273 return AccessController.doPrivileged(new PrivilegedAction<String>() {
274 public String run() {
275 try {
276 return PropertyExpander.expand(value);
277 } catch (GeneralSecurityException e) {
278 throw new ProviderException(e);
279 }
280 }
281 });
282 }
283
284}
java/pkg/sun/security/jca/ProviderList$1.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ProviderList$2.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ProviderList$3.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ProviderList$ServiceList$1.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ProviderList$ServiceList.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ProviderList.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ProviderList.java+504−0
@@ -0,0 +1,504 @@
1/*
2 * Copyright (c) 2003, 2011, 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
26package sun.security.jca;
27
28import java.util.*;
29
30import java.security.*;
31import java.security.Provider.Service;
32
33/**
34 * List of Providers. Used to represent the provider preferences.
35 *
36 * The system starts out with a ProviderList that only has the classNames
37 * of the Providers. Providers are loaded on demand only when needed.
38 *
39 * For compatibility reasons, Providers that could not be loaded are ignored
40 * and internally presented as the instance EMPTY_PROVIDER. However, those
41 * objects cannot be presented to applications. Call the convert() method
42 * to force all Providers to be loaded and to obtain a ProviderList with
43 * invalid entries removed. All this is handled by the Security class.
44 *
45 * Note that all indices used by this class are 0-based per general Java
46 * convention. These must be converted to the 1-based indices used by the
47 * Security class externally when needed.
48 *
49 * Instances of this class are immutable. This eliminates the need for
50 * cloning and synchronization in consumers. The add() and remove() style
51 * methods are static in order to avoid confusion about the immutability.
52 *
53 * @author Andreas Sterbenz
54 * @since 1.5
55 */
56public final class ProviderList {
57
58 final static sun.security.util.Debug debug =
59 sun.security.util.Debug.getInstance("jca", "ProviderList");
60
61 private final static ProviderConfig[] PC0 = new ProviderConfig[0];
62
63 private final static Provider[] P0 = new Provider[0];
64
65 // constant for an ProviderList with no elements
66 static final ProviderList EMPTY = new ProviderList(PC0, true);
67
68 // dummy provider object to use during initialization
69 // used to avoid explicit null checks in various places
70 private static final Provider EMPTY_PROVIDER =
71 new Provider("##Empty##", 1.0d, "initialization in progress") {
72 // override getService() to return null slightly faster
73 public Service getService(String type, String algorithm) {
74 return null;
75 }
76 };
77
78 // construct a ProviderList from the security properties
79 // (static provider configuration in the java.security file)
80 static ProviderList fromSecurityProperties() {
81 // doPrivileged() because of Security.getProperty()
82 return AccessController.doPrivileged(
83 new PrivilegedAction<ProviderList>() {
84 public ProviderList run() {
85 return new ProviderList();
86 }
87 });
88 }
89
90 public static ProviderList add(ProviderList providerList, Provider p) {
91 return insertAt(providerList, p, -1);
92 }
93
94 public static ProviderList insertAt(ProviderList providerList, Provider p,
95 int position) {
96 if (providerList.getProvider(p.getName()) != null) {
97 return providerList;
98 }
99 List<ProviderConfig> list = new ArrayList<>
100 (Arrays.asList(providerList.configs));
101 int n = list.size();
102 if ((position < 0) || (position > n)) {
103 position = n;
104 }
105 list.add(position, new ProviderConfig(p));
106 return new ProviderList(list.toArray(PC0), true);
107 }
108
109 public static ProviderList remove(ProviderList providerList, String name) {
110 // make sure provider exists
111 if (providerList.getProvider(name) == null) {
112 return providerList;
113 }
114 // copy all except matching to new list
115 ProviderConfig[] configs = new ProviderConfig[providerList.size() - 1];
116 int j = 0;
117 for (ProviderConfig config : providerList.configs) {
118 if (config.getProvider().getName().equals(name) == false) {
119 configs[j++] = config;
120 }
121 }
122 return new ProviderList(configs, true);
123 }
124
125 // Create a new ProviderList from the specified Providers.
126 // This method is for use by SunJSSE.
127 public static ProviderList newList(Provider ... providers) {
128 ProviderConfig[] configs = new ProviderConfig[providers.length];
129 for (int i = 0; i < providers.length; i++) {
130 configs[i] = new ProviderConfig(providers[i]);
131 }
132 return new ProviderList(configs, true);
133 }
134
135 // configuration of the providers
136 private final ProviderConfig[] configs;
137
138 // flag indicating whether all configs have been loaded successfully
139 private volatile boolean allLoaded;
140
141 // List returned by providers()
142 private final List<Provider> userList = new AbstractList<Provider>() {
143 public int size() {
144 return configs.length;
145 }
146 public Provider get(int index) {
147 return getProvider(index);
148 }
149 };
150
151 /**
152 * Create a new ProviderList from an array of configs
153 */
154 private ProviderList(ProviderConfig[] configs, boolean allLoaded) {
155 this.configs = configs;
156 this.allLoaded = allLoaded;
157 }
158
159 /**
160 * Return a new ProviderList parsed from the java.security Properties.
161 */
162 private ProviderList() {
163 List<ProviderConfig> configList = new ArrayList<>();
164 for (int i = 1; true; i++) {
165 String entry = Security.getProperty("security.provider." + i);
166 if (entry == null) {
167 break;
168 }
169 entry = entry.trim();
170 if (entry.length() == 0) {
171 System.err.println("invalid entry for " +
172 "security.provider." + i);
173 break;
174 }
175 int k = entry.indexOf(' ');
176 ProviderConfig config;
177 if (k == -1) {
178 config = new ProviderConfig(entry);
179 } else {
180 String className = entry.substring(0, k);
181 String argument = entry.substring(k + 1).trim();
182 config = new ProviderConfig(className, argument);
183 }
184
185 // Get rid of duplicate providers.
186 if (configList.contains(config) == false) {
187 configList.add(config);
188 }
189 }
190 configs = configList.toArray(PC0);
191 if (debug != null) {
192 debug.println("provider configuration: " + configList);
193 }
194 }
195
196 /**
197 * Construct a special ProviderList for JAR verification. It consists
198 * of the providers specified via jarClassNames, which must be on the
199 * bootclasspath and cannot be in signed JAR files. This is to avoid
200 * possible recursion and deadlock during verification.
201 */
202 ProviderList getJarList(String[] jarClassNames) {
203 List<ProviderConfig> newConfigs = new ArrayList<>();
204 for (String className : jarClassNames) {
205 ProviderConfig newConfig = new ProviderConfig(className);
206 for (ProviderConfig config : configs) {
207 // if the equivalent object is present in this provider list,
208 // use the old object rather than the new object.
209 // this ensures that when the provider is loaded in the
210 // new thread local list, it will also become available
211 // in this provider list
212 if (config.equals(newConfig)) {
213 newConfig = config;
214 break;
215 }
216 }
217 newConfigs.add(newConfig);
218 }
219 ProviderConfig[] configArray = newConfigs.toArray(PC0);
220 return new ProviderList(configArray, false);
221 }
222
223 public int size() {
224 return configs.length;
225 }
226
227 /**
228 * Return the Provider at the specified index. Returns EMPTY_PROVIDER
229 * if the provider could not be loaded at this time.
230 */
231 Provider getProvider(int index) {
232 Provider p = configs[index].getProvider();
233 return (p != null) ? p : EMPTY_PROVIDER;
234 }
235
236 /**
237 * Return an unmodifiable List of all Providers in this List. The
238 * individual Providers are loaded on demand. Elements that could not
239 * be initialized are replaced with EMPTY_PROVIDER.
240 */
241 public List<Provider> providers() {
242 return userList;
243 }
244
245 private ProviderConfig getProviderConfig(String name) {
246 int index = getIndex(name);
247 return (index != -1) ? configs[index] : null;
248 }
249
250 // return the Provider with the specified name or null
251 public Provider getProvider(String name) {
252 ProviderConfig config = getProviderConfig(name);
253 return (config == null) ? null : config.getProvider();
254 }
255
256 /**
257 * Return the index at which the provider with the specified name is
258 * installed or -1 if it is not present in this ProviderList.
259 */
260 public int getIndex(String name) {
261 for (int i = 0; i < configs.length; i++) {
262 Provider p = getProvider(i);
263 if (p.getName().equals(name)) {
264 return i;
265 }
266 }
267 return -1;
268 }
269
270 // attempt to load all Providers not already loaded
271 private int loadAll() {
272 if (allLoaded) {
273 return configs.length;
274 }
275 if (debug != null) {
276 debug.println("Loading all providers");
277 new Exception("Call trace").printStackTrace();
278 }
279 int n = 0;
280 for (int i = 0; i < configs.length; i++) {
281 Provider p = configs[i].getProvider();
282 if (p != null) {
283 n++;
284 }
285 }
286 if (n == configs.length) {
287 allLoaded = true;
288 }
289 return n;
290 }
291
292 /**
293 * Try to load all Providers and return the ProviderList. If one or
294 * more Providers could not be loaded, a new ProviderList with those
295 * entries removed is returned. Otherwise, the method returns this.
296 */
297 ProviderList removeInvalid() {
298 int n = loadAll();
299 if (n == configs.length) {
300 return this;
301 }
302 ProviderConfig[] newConfigs = new ProviderConfig[n];
303 for (int i = 0, j = 0; i < configs.length; i++) {
304 ProviderConfig config = configs[i];
305 if (config.isLoaded()) {
306 newConfigs[j++] = config;
307 }
308 }
309 return new ProviderList(newConfigs, true);
310 }
311
312 // return the providers as an array
313 public Provider[] toArray() {
314 return providers().toArray(P0);
315 }
316
317 // return a String representation of this ProviderList
318 public String toString() {
319 return Arrays.asList(configs).toString();
320 }
321
322 /**
323 * Return a Service describing an implementation of the specified
324 * algorithm from the Provider with the highest precedence that
325 * supports that algorithm. Return null if no Provider supports this
326 * algorithm.
327 */
328 public Service getService(String type, String name) {
329 for (int i = 0; i < configs.length; i++) {
330 Provider p = getProvider(i);
331 Service s = p.getService(type, name);
332 if (s != null) {
333 return s;
334 }
335 }
336 return null;
337 }
338
339 /**
340 * Return a List containing all the Services describing implementations
341 * of the specified algorithms in precedence order. If no implementation
342 * exists, this method returns an empty List.
343 *
344 * The elements of this list are determined lazily on demand.
345 *
346 * The List returned is NOT thread safe.
347 */
348 public List<Service> getServices(String type, String algorithm) {
349 return new ServiceList(type, algorithm);
350 }
351
352 /**
353 * This method exists for compatibility with JCE only. It will be removed
354 * once JCE has been changed to use the replacement method.
355 * @deprecated use getServices(List<ServiceId>) instead
356 */
357 @Deprecated
358 public List<Service> getServices(String type, List<String> algorithms) {
359 List<ServiceId> ids = new ArrayList<>();
360 for (String alg : algorithms) {
361 ids.add(new ServiceId(type, alg));
362 }
363 return getServices(ids);
364 }
365
366 public List<Service> getServices(List<ServiceId> ids) {
367 return new ServiceList(ids);
368 }
369
370 /**
371 * Inner class for a List of Services. Custom List implementation in
372 * order to delay Provider initialization and lookup.
373 * Not thread safe.
374 */
375 private final class ServiceList extends AbstractList<Service> {
376
377 // type and algorithm for simple lookup
378 // avoid allocating/traversing the ServiceId list for these lookups
379 private final String type;
380 private final String algorithm;
381
382 // list of ids for parallel lookup
383 // if ids is non-null, type and algorithm are null
384 private final List<ServiceId> ids;
385
386 // first service we have found
387 // it is stored in a separate variable so that we can avoid
388 // allocating the services list if we do not need the second service.
389 // this is the case if we don't failover (failovers are typically rare)
390 private Service firstService;
391
392 // list of the services we have found so far
393 private List<Service> services;
394
395 // index into config[] of the next provider we need to query
396 private int providerIndex;
397
398 ServiceList(String type, String algorithm) {
399 this.type = type;
400 this.algorithm = algorithm;
401 this.ids = null;
402 }
403
404 ServiceList(List<ServiceId> ids) {
405 this.type = null;
406 this.algorithm = null;
407 this.ids = ids;
408 }
409
410 private void addService(Service s) {
411 if (firstService == null) {
412 firstService = s;
413 } else {
414 if (services == null) {
415 services = new ArrayList<Service>(4);
416 services.add(firstService);
417 }
418 services.add(s);
419 }
420 }
421
422 private Service tryGet(int index) {
423 while (true) {
424 if ((index == 0) && (firstService != null)) {
425 return firstService;
426 } else if ((services != null) && (services.size() > index)) {
427 return services.get(index);
428 }
429 if (providerIndex >= configs.length) {
430 return null;
431 }
432 // check all algorithms in this provider before moving on
433 Provider p = getProvider(providerIndex++);
434 if (type != null) {
435 // simple lookup
436 Service s = p.getService(type, algorithm);
437 if (s != null) {
438 addService(s);
439 }
440 } else {
441 // parallel lookup
442 for (ServiceId id : ids) {
443 Service s = p.getService(id.type, id.algorithm);
444 if (s != null) {
445 addService(s);
446 }
447 }
448 }
449 }
450 }
451
452 public Service get(int index) {
453 Service s = tryGet(index);
454 if (s == null) {
455 throw new IndexOutOfBoundsException();
456 }
457 return s;
458 }
459
460 public int size() {
461 int n;
462 if (services != null) {
463 n = services.size();
464 } else {
465 n = (firstService != null) ? 1 : 0;
466 }
467 while (tryGet(n) != null) {
468 n++;
469 }
470 return n;
471 }
472
473 // override isEmpty() and iterator() to not call size()
474 // this avoids loading + checking all Providers
475
476 public boolean isEmpty() {
477 return (tryGet(0) == null);
478 }
479
480 public Iterator<Service> iterator() {
481 return new Iterator<Service>() {
482 int index;
483
484 public boolean hasNext() {
485 return tryGet(index) != null;
486 }
487
488 public Service next() {
489 Service s = tryGet(index);
490 if (s == null) {
491 throw new NoSuchElementException();
492 }
493 index++;
494 return s;
495 }
496
497 public void remove() {
498 throw new UnsupportedOperationException();
499 }
500 };
501 }
502 }
503
504}
java/pkg/sun/security/jca/Providers.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/Providers.java+250−0
@@ -0,0 +1,250 @@
1/*
2 * Copyright (c) 2003, 2011, 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
26package sun.security.jca;
27
28import java.util.*;
29
30import java.security.Provider;
31import java.security.Security;
32
33/**
34 * Collection of methods to get and set provider list. Also includes
35 * special code for the provider list during JAR verification.
36 *
37 * @author Andreas Sterbenz
38 * @since 1.5
39 */
40public class Providers {
41
42 private static final ThreadLocal<ProviderList> threadLists =
43 new InheritableThreadLocal<>();
44
45 // number of threads currently using thread-local provider lists
46 // tracked to allow an optimization if == 0
47 private static volatile int threadListsUsed;
48
49 // current system-wide provider list
50 // Note volatile immutable object, so no synchronization needed.
51 private static volatile ProviderList providerList;
52
53 static {
54 // set providerList to empty list first in case initialization somehow
55 // triggers a getInstance() call (although that should not happen)
56 providerList = ProviderList.EMPTY;
57 providerList = ProviderList.fromSecurityProperties();
58 }
59
60 private Providers() {
61 // empty
62 }
63
64 // we need special handling to resolve circularities when loading
65 // signed JAR files during startup. The code below is part of that.
66
67 // Basically, before we load data from a signed JAR file, we parse
68 // the PKCS#7 file and verify the signature. We need a
69 // CertificateFactory, Signatures, etc. to do that. We have to make
70 // sure that we do not try to load the implementation from the JAR
71 // file we are just verifying.
72 //
73 // To avoid that, we use different provider settings during JAR
74 // verification. However, we do not want those provider settings to
75 // interfere with other parts of the system. Therefore, we make them local
76 // to the Thread executing the JAR verification code.
77 //
78 // The code here is used by sun.security.util.SignatureFileVerifier.
79 // See there for details.
80
81 private static final String BACKUP_PROVIDER_CLASSNAME =
82 "sun.security.provider.VerificationProvider";
83
84 // Hardcoded classnames of providers to use for JAR verification.
85 // MUST NOT be on the bootclasspath and not in signed JAR files.
86 private static final String[] jarVerificationProviders = {
87 "sun.security.provider.Sun",
88 "sun.security.rsa.SunRsaSign",
89 // Note: SunEC *is* in a signed JAR file, but it's not signed
90 // by EC itself. So it's still safe to be listed here.
91 "sun.security.ec.SunEC",
92 BACKUP_PROVIDER_CLASSNAME,
93 };
94
95 // Return to Sun provider or its backup.
96 // This method should only be called by
97 // sun.security.util.ManifestEntryVerifier and java.security.SecureRandom.
98 public static Provider getSunProvider() {
99 try {
100 Class clazz = Class.forName(jarVerificationProviders[0]);
101 return (Provider)clazz.newInstance();
102 } catch (Exception e) {
103 try {
104 Class clazz = Class.forName(BACKUP_PROVIDER_CLASSNAME);
105 return (Provider)clazz.newInstance();
106 } catch (Exception ee) {
107 throw new RuntimeException("Sun provider not found", e);
108 }
109 }
110 }
111
112 /**
113 * Start JAR verification. This sets a special provider list for
114 * the current thread. You MUST save the return value from this
115 * method and you MUST call stopJarVerification() with that object
116 * once you are done.
117 */
118 public static Object startJarVerification() {
119 ProviderList currentList = getProviderList();
120 ProviderList jarList = currentList.getJarList(jarVerificationProviders);
121 // return the old thread-local provider list, usually null
122 return beginThreadProviderList(jarList);
123 }
124
125 /**
126 * Stop JAR verification. Call once you have completed JAR verification.
127 */
128 public static void stopJarVerification(Object obj) {
129 // restore old thread-local provider list
130 endThreadProviderList((ProviderList)obj);
131 }
132
133 /**
134 * Return the current ProviderList. If the thread-local list is set,
135 * it is returned. Otherwise, the system wide list is returned.
136 */
137 public static ProviderList getProviderList() {
138 ProviderList list = getThreadProviderList();
139 if (list == null) {
140 list = getSystemProviderList();
141 }
142 return list;
143 }
144
145 /**
146 * Set the current ProviderList. Affects the thread-local list if set,
147 * otherwise the system wide list.
148 */
149 public static void setProviderList(ProviderList newList) {
150 if (getThreadProviderList() == null) {
151 setSystemProviderList(newList);
152 } else {
153 changeThreadProviderList(newList);
154 }
155 }
156
157 /**
158 * Get the full provider list with invalid providers (those that
159 * could not be loaded) removed. This is the list we need to
160 * present to applications.
161 */
162 public static ProviderList getFullProviderList() {
163 ProviderList list;
164 synchronized (Providers.class) {
165 list = getThreadProviderList();
166 if (list != null) {
167 ProviderList newList = list.removeInvalid();
168 if (newList != list) {
169 changeThreadProviderList(newList);
170 list = newList;
171 }
172 return list;
173 }
174 }
175 list = getSystemProviderList();
176 ProviderList newList = list.removeInvalid();
177 if (newList != list) {
178 setSystemProviderList(newList);
179 list = newList;
180 }
181 return list;
182 }
183
184 private static ProviderList getSystemProviderList() {
185 return providerList;
186 }
187
188 private static void setSystemProviderList(ProviderList list) {
189 providerList = list;
190 }
191
192 public static ProviderList getThreadProviderList() {
193 // avoid accessing the threadlocal if none are currently in use
194 // (first use of ThreadLocal.get() for a Thread allocates a Map)
195 if (threadListsUsed == 0) {
196 return null;
197 }
198 return threadLists.get();
199 }
200
201 // Change the thread local provider list. Use only if the current thread
202 // is already using a thread local list and you want to change it in place.
203 // In other cases, use the begin/endThreadProviderList() methods.
204 private static void changeThreadProviderList(ProviderList list) {
205 threadLists.set(list);
206 }
207
208 /**
209 * Methods to manipulate the thread local provider list. It is for use by
210 * JAR verification (see above) and the SunJSSE FIPS mode only.
211 *
212 * It should be used as follows:
213 *
214 * ProviderList list = ...;
215 * ProviderList oldList = Providers.beginThreadProviderList(list);
216 * try {
217 * // code that needs thread local provider list
218 * } finally {
219 * Providers.endThreadProviderList(oldList);
220 * }
221 *
222 */
223
224 public static synchronized ProviderList beginThreadProviderList(ProviderList list) {
225 if (ProviderList.debug != null) {
226 ProviderList.debug.println("ThreadLocal providers: " + list);
227 }
228 ProviderList oldList = threadLists.get();
229 threadListsUsed++;
230 threadLists.set(list);
231 return oldList;
232 }
233
234 public static synchronized void endThreadProviderList(ProviderList list) {
235 if (list == null) {
236 if (ProviderList.debug != null) {
237 ProviderList.debug.println("Disabling ThreadLocal providers");
238 }
239 threadLists.remove();
240 } else {
241 if (ProviderList.debug != null) {
242 ProviderList.debug.println
243 ("Restoring previous ThreadLocal providers: " + list);
244 }
245 threadLists.set(list);
246 }
247 threadListsUsed--;
248 }
249
250}
java/pkg/sun/security/jca/ServiceId.class+0−0

Binary file not shown.

java/pkg/sun/security/jca/ServiceId.java+45−0
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2003, 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
26package sun.security.jca;
27
28/**
29 * Simple class encapsulating a service type and algorithm for lookup.
30 * Put in a separate file rather than nested to allow import via ...jca.*.
31 *
32 * @author Andreas Sterbenz
33 * @since 1.5
34 */
35public final class ServiceId {
36
37 public final String type;
38 public final String algorithm;
39
40 public ServiceId(String type, String algorithm) {
41 this.type = type;
42 this.algorithm = algorithm;
43 }
44
45}
java/pkg/sun/security/jca/mkfile+13−0
@@ -0,0 +1,13 @@
1<../../../../../mkconfig
2
3TARG=\
4 GetInstance.dis\
5 JCAUtil.dis\
6 ProviderConfig.dis\
7 ProviderList.dis\
8 Providers.dis\
9 ServiceId.dis\
10
11DISBIN=$ROOT/java/dis/java/java/sun/security/jca
12
13<$ROOT/mkfiles/mkjava

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t