blob: f6b21ba257dfe6499b084326da408c449a4056aa [file] [log] [blame]
/*
* This file is part of the QuickServer library
* Copyright (C) QuickServer.org
*
* Use, modification, copying and distribution of this software is subject to
* the terms and conditions of the GNU Lesser General Public License.
* You should have received a copy of the GNU LGP License along with this
* library; if not, you can download a copy from <http://www.quickserver.org/>.
*
* For questions, suggestions, bug-reports, enhancement-requests etc.
* visit http://www.quickserver.org
*
*/
package org.quickserver.security;
import java.io.*;
import java.util.logging.*;
import org.quickserver.util.xmlreader.*;
import org.quickserver.util.io.*;
import javax.net.ssl.*;
import java.security.*;
import org.quickserver.swing.*;
/**
* Class that loads Key Managers, Trust Managers, SSLContext and other secure
* objects from QuickServer configuration passed. See &lt;secure-store-manager&gt;
* in &lt;secure-store&gt; to set new manger to load your SecureStore. This
* class can be overridden to change the way QuickServer configures the
* secure mode.
* @see org.quickserver.util.xmlreader.SecureStore
* @author Akshathkumar Shetty
* @since 1.4
*/
public class SecureStoreManager {
private static Logger logger = Logger.getLogger(
SecureStoreManager.class.getName());
private SensitiveInput sensitiveInput = null;
/**
* Loads KeyManagers. KeyManagers are responsible for managing
* the key material which is used to authenticate the local
* SSLSocket to its peer. Can return null.
*/
public KeyManager[] loadKeyManagers(QuickServerConfig config)
throws GeneralSecurityException, IOException {
Secure secure = config.getSecure();
SecureStore secureStore = secure.getSecureStore();
if(secureStore==null) {
logger.fine("SecureStore configuration not set! "+
"So returning null for KeyManager");
return null;
}
KeyStoreInfo keyStoreInfo = secureStore.getKeyStoreInfo();
if(keyStoreInfo==null) {
logger.fine("KeyStoreInfo configuration not set! "+
"So returning null for KeyManager");
return null;
}
logger.finest("Loading KeyManagers");
KeyStore ks = getKeyStoreForKey(secureStore.getType(),
secureStore.getProvider());
logger.info("KeyManager Provider: "+ks.getProvider());
char storepass[] = null;
if(keyStoreInfo.getStorePassword()!=null) {
logger.finest("KeyStore: Store password was present!");
storepass = keyStoreInfo.getStorePassword().toCharArray();
} else {
logger.finest("KeyStore: Store password was not set.. so asking!");
if(sensitiveInput==null) {
sensitiveInput = new SensitiveInput(config.getName()+" - Input Prompt");
}
storepass = sensitiveInput.getInput("Store password for KeyStore");
if(storepass==null) {
logger.finest("No password entered.. will pass null");
}
}
InputStream keyStoreStream = null;
try {
if(keyStoreInfo.getStoreFile().equalsIgnoreCase("none")==false) {
logger.finest("KeyStore location: "+
ConfigReader.makeAbsoluteToConfig(keyStoreInfo.getStoreFile(),
config));
keyStoreStream = new FileInputStream(
ConfigReader.makeAbsoluteToConfig(keyStoreInfo.getStoreFile(),
config));
}
ks.load(keyStoreStream, storepass);
logger.finest("KeyStore loaded");
} finally {
if(keyStoreStream != null) {
keyStoreStream.close();
keyStoreStream = null;
}
}
char keypass[] = null;
if(keyStoreInfo.getKeyPassword()!=null) {
logger.finest("KeyStore: key password was present!");
keypass = keyStoreInfo.getKeyPassword().toCharArray();
} else {
logger.finest("KeyStore: Key password was not set.. so asking!");
if(sensitiveInput==null) {
sensitiveInput = new SensitiveInput(config.getName()+" - Input Prompt");
}
keypass = sensitiveInput.getInput("Key password for KeyStore");
if(keypass==null) {
logger.finest("No password entered.. will pass blank");
keypass = "".toCharArray();
}
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(
secureStore.getAlgorithm());
kmf.init(ks, keypass);
storepass = " ".toCharArray();
storepass = null;
keypass = " ".toCharArray();
keypass = null;
return kmf.getKeyManagers();
}
/**
* Loads TrustManagers. TrustManagers are responsible for managing the
* trust material that is used when making trust decisions, and for
* deciding whether credentials presented by a peer should be accepted.
* Can return null.
*/
public TrustManager[] loadTrustManagers(QuickServerConfig config)
throws GeneralSecurityException, IOException {
Secure secure = config.getSecure();
SecureStore secureStore = secure.getSecureStore();
TrustStoreInfo trustStoreInfo = secureStore.getTrustStoreInfo();
if(trustStoreInfo==null) {
return null;
}
logger.finest("Loading TrustManagers");
String type = null;
if(trustStoreInfo.getType()!=null && trustStoreInfo.getType().trim().length()!=0)
type = trustStoreInfo.getType();
else
type = secureStore.getType();
String provider = null;
if(trustStoreInfo.getProvider()!=null && trustStoreInfo.getProvider().trim().length()!=0)
provider = trustStoreInfo.getProvider();
else
provider = secureStore.getProvider();
KeyStore ts = getKeyStoreForTrust(type, provider);
char trustpass[] = null;
if(trustStoreInfo.getStorePassword()!=null) {
logger.finest("TrustStore: Store password was present!");
trustpass = trustStoreInfo.getStorePassword().toCharArray();
} else {
logger.finest("TrustStore: Store password was not set.. so asking!");
if(sensitiveInput==null) {
sensitiveInput = new SensitiveInput(config.getName()+" - Input Prompt");
}
trustpass = sensitiveInput.getInput("Store password for TrustStore");
if(trustpass==null) {
logger.finest("No password entered.. will pass null");
}
}
InputStream trustStoreStream = null;
try {
if(trustStoreInfo.getStoreFile().equalsIgnoreCase("none")==false) {
logger.finest("TrustStore location: "+
ConfigReader.makeAbsoluteToConfig(
trustStoreInfo.getStoreFile(), config));
trustStoreStream = new FileInputStream(
ConfigReader.makeAbsoluteToConfig(
trustStoreInfo.getStoreFile(), config));
}
ts.load(trustStoreStream, trustpass);
logger.finest("TrustStore loaded");
} finally {
if(trustStoreStream!=null) {
trustStoreStream.close();
trustStoreStream = null;
}
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
secureStore.getAlgorithm());
tmf.init(ts);
return tmf.getTrustManagers();
}
/**
* Generates a SSLContext object that implements the specified secure
* socket protocol.
*/
public SSLContext getSSLContext(String protocol)
throws NoSuchAlgorithmException {
return SSLContext.getInstance(protocol);
}
public SSLContext getSSLContext(QuickServerConfig config)
throws NoSuchAlgorithmException, NoSuchProviderException {
if(config.getSecure().getSecureStore().getProvider()!=null) {
return SSLContext.getInstance(
config.getSecure().getProtocol(),
config.getSecure().getSecureStore().getProvider());
} else {
return SSLContext.getInstance(config.getSecure().getProtocol());
}
}
/**
* Generates a keystore object for the specified keystore type from
* the specified provider to be used for loading/storeing keys.
* @param type the type of keystore
* @param provider the name of the provider if <code>null</code> any
* provider package that implements this type of key may be given based
* on the priority.
*/
protected KeyStore getKeyStoreForKey(String type, String provider)
throws KeyStoreException, NoSuchProviderException {
if(provider==null)
return KeyStore.getInstance(type);
return KeyStore.getInstance(type, provider);
}
/**
* Generates a keystore object for the specified keystore type from
* the specified provider to be used for loading/storing trusted
* keys/certificates.
* @param type the type of keystore
* @param provider the name of the provider if <code>null</code> any
* provider package that implements this type of key may be given based
* on the priority.
*/
protected KeyStore getKeyStoreForTrust(String type, String provider)
throws KeyStoreException, NoSuchProviderException {
if(provider==null)
return KeyStore.getInstance(type);
return KeyStore.getInstance(type, provider);
}
/**
* Returns a SSLSocketFactory object to be used for creating SSLSockets.
*/
public SSLSocketFactory getSocketFactory(SSLContext context) {
return context.getSocketFactory();
}
/**
* Can be used to log details about the SSLServerSocket used to
* create a secure server [SSL/TLS]. This method can also be
* overridden to change the enabled cipher suites and/or enabled protocols.
*/
public void logSSLServerSocketInfo(SSLServerSocket sslServerSocket) {
if(logger.isLoggable(Level.FINEST)==false) {
return;
}
logger.finest("SecureServer Info: ClientAuth: "+
sslServerSocket.getNeedClientAuth());
logger.finest("SecureServer Info: ClientMode: "+
sslServerSocket.getUseClientMode());
String supportedSuites[] = sslServerSocket.getSupportedCipherSuites();
logger.finest("SecureServer Info: Supported Cipher Suites --------");
for(int i=0;i<supportedSuites.length;i++)
logger.finest(supportedSuites[i]);
logger.finest("---------------------------------------------------");
String enabledSuites[] = sslServerSocket.getEnabledCipherSuites();
logger.finest("SecureServer Info: Enabled Cipher Suites ----------");
for(int i=0;i<enabledSuites.length;i++)
logger.finest(enabledSuites[i]);
logger.finest("---------------------------------------------------");
String supportedProtocols[] = sslServerSocket.getSupportedProtocols();
logger.finest("SecureServer Info: Supported Protocols ------------");
for(int i=0;i<supportedProtocols.length;i++)
logger.finest(supportedProtocols[i]);
logger.finest("---------------------------------------------------");
String enabledProtocols[] = sslServerSocket.getEnabledProtocols();
logger.finest("SecureServer Info: Enabled Protocols --------------");
for(int i=0;i<enabledProtocols.length;i++)
logger.finest(enabledProtocols[i]);
logger.finest("---------------------------------------------------");
}
}