Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/jca/ProviderConfig.java
38831 views
1
/*
2
* Copyright (c) 2003, 2016, 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 sun.security.jca;
27
28
import java.io.File;
29
import java.lang.reflect.*;
30
31
import java.security.*;
32
33
import 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
*/
43
final 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
} catch (ExceptionInInitializerError err) {
259
// unexpected exception thrown from static initialization block in provider
260
// (ex: insufficient permission to initialize provider class)
261
if (debug != null) {
262
debug.println("Error loading provider " + ProviderConfig.this);
263
err.printStackTrace();
264
}
265
disableLoad();
266
return null;
267
}
268
}
269
});
270
}
271
272
/**
273
* Perform property expansion of the provider value.
274
*
275
* NOTE use of doPrivileged().
276
*/
277
private static String expand(final String value) {
278
// shortcut if value does not contain any properties
279
if (value.contains("${") == false) {
280
return value;
281
}
282
return AccessController.doPrivileged(new PrivilegedAction<String>() {
283
public String run() {
284
try {
285
return PropertyExpander.expand(value);
286
} catch (GeneralSecurityException e) {
287
throw new ProviderException(e);
288
}
289
}
290
});
291
}
292
293
}
294
295