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