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/ProviderConfig.java (1 of 18352 files). Show all

Unified · Split

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+
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+ }
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+}