001: /*
002: * This file is part of the QuickServer library
003: * Copyright (C) QuickServer.org
004: *
005: * Use, modification, copying and distribution of this software is subject to
006: * the terms and conditions of the GNU Lesser General Public License.
007: * You should have received a copy of the GNU LGP License along with this
008: * library; if not, you can download a copy from <http://www.quickserver.org/>.
009: *
010: * For questions, suggestions, bug-reports, enhancement-requests etc.
011: * visit http://www.quickserver.org
012: *
013: */
014:
015: package org.quickserver.security;
016:
017: import java.io.*;
018: import java.util.logging.*;
019: import org.quickserver.util.xmlreader.*;
020: import org.quickserver.util.io.*;
021: import javax.net.ssl.*;
022: import java.security.*;
023: import org.quickserver.swing.*;
024:
025: /**
026: * Class that loads Key Managers, Trust Managers, SSLContext and other secure
027: * objects from QuickServer configuration passed. See <secure-store-manager>
028: * in <secure-store> to set new manger to load your SecureStore. This
029: * class can be overridden to change the way QuickServer configures the
030: * secure mode.
031: * @see org.quickserver.util.xmlreader.SecureStore
032: * @author Akshathkumar Shetty
033: * @since 1.4
034: */
035: public class SecureStoreManager {
036: private static Logger logger = Logger
037: .getLogger(SecureStoreManager.class.getName());
038: private SensitiveInput sensitiveInput = null;
039:
040: /**
041: * Loads KeyManagers. KeyManagers are responsible for managing
042: * the key material which is used to authenticate the local
043: * SSLSocket to its peer. Can return null.
044: */
045: public KeyManager[] loadKeyManagers(QuickServerConfig config)
046: throws GeneralSecurityException, IOException {
047: Secure secure = config.getSecure();
048: SecureStore secureStore = secure.getSecureStore();
049:
050: if (secureStore == null) {
051: logger.fine("SecureStore configuration not set! "
052: + "So returning null for KeyManager");
053: return null;
054: }
055:
056: KeyStoreInfo keyStoreInfo = secureStore.getKeyStoreInfo();
057: if (keyStoreInfo == null) {
058: logger.fine("KeyStoreInfo configuration not set! "
059: + "So returning null for KeyManager");
060: return null;
061: }
062:
063: logger.finest("Loading KeyManagers");
064: KeyStore ks = getKeyStoreForKey(secureStore.getType(),
065: secureStore.getProvider());
066:
067: char storepass[] = null;
068: if (keyStoreInfo.getStorePassword() != null) {
069: logger.finest("KeyStore: Store password was present!");
070: storepass = keyStoreInfo.getStorePassword().toCharArray();
071: } else {
072: logger
073: .finest("KeyStore: Store password was not set.. so asking!");
074: if (sensitiveInput == null) {
075: sensitiveInput = new SensitiveInput(config.getName()
076: + " - Input Prompt");
077: }
078: storepass = sensitiveInput
079: .getInput("Store password for KeyStore");
080: if (storepass == null) {
081: logger.finest("No password entered.. will pass null");
082: }
083: }
084:
085: InputStream keyStoreStream = null;
086: try {
087: if (keyStoreInfo.getStoreFile().equalsIgnoreCase("none") == false) {
088: logger.finest("KeyStore location: "
089: + ConfigReader.makeAbsoluteToConfig(
090: keyStoreInfo.getStoreFile(), config));
091: keyStoreStream = new FileInputStream(ConfigReader
092: .makeAbsoluteToConfig(keyStoreInfo
093: .getStoreFile(), config));
094: }
095:
096: ks.load(keyStoreStream, storepass);
097: logger.finest("KeyStore loaded");
098: } finally {
099: if (keyStoreStream != null) {
100: keyStoreStream.close();
101: keyStoreStream = null;
102: }
103: }
104:
105: char keypass[] = null;
106: if (keyStoreInfo.getKeyPassword() != null) {
107: logger.finest("KeyStore: key password was present!");
108: keypass = keyStoreInfo.getKeyPassword().toCharArray();
109: } else {
110: logger
111: .finest("KeyStore: Key password was not set.. so asking!");
112: if (sensitiveInput == null) {
113: sensitiveInput = new SensitiveInput(config.getName()
114: + " - Input Prompt");
115: }
116: keypass = sensitiveInput
117: .getInput("Key password for KeyStore");
118: if (keypass == null) {
119: logger.finest("No password entered.. will pass blank");
120: keypass = "".toCharArray();
121: }
122: }
123:
124: KeyManagerFactory kmf = KeyManagerFactory
125: .getInstance(secureStore.getAlgorithm());
126: kmf.init(ks, keypass);
127:
128: storepass = " ".toCharArray();
129: storepass = null;
130: keypass = " ".toCharArray();
131: keypass = null;
132:
133: return kmf.getKeyManagers();
134: }
135:
136: /**
137: * Loads TrustManagers. TrustManagers are responsible for managing the
138: * trust material that is used when making trust decisions, and for
139: * deciding whether credentials presented by a peer should be accepted.
140: * Can return null.
141: */
142: public TrustManager[] loadTrustManagers(QuickServerConfig config)
143: throws GeneralSecurityException, IOException {
144: Secure secure = config.getSecure();
145: SecureStore secureStore = secure.getSecureStore();
146: TrustStoreInfo trustStoreInfo = secureStore.getTrustStoreInfo();
147:
148: if (trustStoreInfo == null) {
149: return null;
150: }
151:
152: logger.finest("Loading TrustManagers");
153:
154: String type = null;
155: if (trustStoreInfo.getType() != null
156: && trustStoreInfo.getType().trim().length() != 0)
157: type = trustStoreInfo.getType();
158: else
159: type = secureStore.getType();
160:
161: String provider = null;
162: if (trustStoreInfo.getProvider() != null
163: && trustStoreInfo.getProvider().trim().length() != 0)
164: provider = trustStoreInfo.getProvider();
165: else
166: provider = secureStore.getProvider();
167:
168: KeyStore ts = getKeyStoreForTrust(type, provider);
169:
170: char trustpass[] = null;
171: if (trustStoreInfo.getStorePassword() != null) {
172: logger.finest("TrustStore: Store password was present!");
173: trustpass = trustStoreInfo.getStorePassword().toCharArray();
174: } else {
175: logger
176: .finest("TrustStore: Store password was not set.. so asking!");
177: if (sensitiveInput == null) {
178: sensitiveInput = new SensitiveInput(config.getName()
179: + " - Input Prompt");
180: }
181: trustpass = sensitiveInput
182: .getInput("Store password for TrustStore");
183: if (trustpass == null) {
184: logger.finest("No password entered.. will pass null");
185: }
186: }
187:
188: InputStream trustStoreStream = null;
189: try {
190: if (trustStoreInfo.getStoreFile().equalsIgnoreCase("none") == false) {
191: logger.finest("TrustStore location: "
192: + ConfigReader.makeAbsoluteToConfig(
193: trustStoreInfo.getStoreFile(), config));
194: trustStoreStream = new FileInputStream(ConfigReader
195: .makeAbsoluteToConfig(trustStoreInfo
196: .getStoreFile(), config));
197: }
198:
199: ts.load(trustStoreStream, trustpass);
200: logger.finest("TrustStore loaded");
201: } finally {
202: if (trustStoreStream != null) {
203: trustStoreStream.close();
204: trustStoreStream = null;
205: }
206: }
207:
208: TrustManagerFactory tmf = TrustManagerFactory
209: .getInstance(secureStore.getAlgorithm());
210: tmf.init(ts);
211: return tmf.getTrustManagers();
212: }
213:
214: /**
215: * Generates a SSLContext object that implements the specified secure
216: * socket protocol.
217: */
218: public SSLContext getSSLContext(String protocol)
219: throws NoSuchAlgorithmException {
220: return SSLContext.getInstance(protocol);
221: }
222:
223: /**
224: * Generates a keystore object for the specified keystore type from
225: * the specified provider to be used for loading/storeing keys.
226: * @param type the type of keystore
227: * @param provider the name of the provider if <code>null</code> any
228: * provider package that implements this type of key may be given based
229: * on the priority.
230: */
231: protected KeyStore getKeyStoreForKey(String type, String provider)
232: throws KeyStoreException, NoSuchProviderException {
233: if (provider == null)
234: return KeyStore.getInstance(type);
235: return KeyStore.getInstance(type, provider);
236: }
237:
238: /**
239: * Generates a keystore object for the specified keystore type from
240: * the specified provider to be used for loading/storing trusted
241: * keys/certificates.
242: * @param type the type of keystore
243: * @param provider the name of the provider if <code>null</code> any
244: * provider package that implements this type of key may be given based
245: * on the priority.
246: */
247: protected KeyStore getKeyStoreForTrust(String type, String provider)
248: throws KeyStoreException, NoSuchProviderException {
249: if (provider == null)
250: return KeyStore.getInstance(type);
251: return KeyStore.getInstance(type, provider);
252: }
253:
254: /**
255: * Returns a SSLSocketFactory object to be used for creating SSLSockets.
256: */
257: public SSLSocketFactory getSocketFactory(SSLContext context) {
258: return context.getSocketFactory();
259: }
260:
261: /**
262: * Can be used to log details about the SSLServerSocket used to
263: * create a secure server [SSL/TLS]. This method can also be
264: * overridden to change the enabled cipher suites and/or enabled protocols.
265: */
266: public void logSSLServerSocketInfo(SSLServerSocket sslServerSocket) {
267: if (logger.isLoggable(Level.FINEST) == false) {
268: return;
269: }
270: logger.finest("SecureServer Info: ClientAuth: "
271: + sslServerSocket.getNeedClientAuth());
272: logger.finest("SecureServer Info: ClientMode: "
273: + sslServerSocket.getUseClientMode());
274:
275: String supportedSuites[] = sslServerSocket
276: .getSupportedCipherSuites();
277: logger
278: .finest("SecureServer Info: Supported Cipher Suites --------");
279: for (int i = 0; i < supportedSuites.length; i++)
280: logger.finest(supportedSuites[i]);
281: logger
282: .finest("---------------------------------------------------");
283:
284: String enabledSuites[] = sslServerSocket
285: .getEnabledCipherSuites();
286: logger
287: .finest("SecureServer Info: Enabled Cipher Suites ----------");
288: for (int i = 0; i < enabledSuites.length; i++)
289: logger.finest(enabledSuites[i]);
290: logger
291: .finest("---------------------------------------------------");
292:
293: String supportedProtocols[] = sslServerSocket
294: .getSupportedProtocols();
295: logger
296: .finest("SecureServer Info: Supported Protocols ------------");
297: for (int i = 0; i < supportedProtocols.length; i++)
298: logger.finest(supportedProtocols[i]);
299: logger
300: .finest("---------------------------------------------------");
301:
302: String enabledProtocols[] = sslServerSocket
303: .getEnabledProtocols();
304: logger
305: .finest("SecureServer Info: Enabled Protocols --------------");
306: for (int i = 0; i < enabledProtocols.length; i++)
307: logger.finest(enabledProtocols[i]);
308: logger
309: .finest("---------------------------------------------------");
310: }
311: }
|