📄 jxsslsocketfactory.java
字号:
package com.ca.commons.security;
/**
* JXSSLSocketFactory.java
*/
import java.io.*;
import java.net.*;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import java.security.*;
import java.awt.*;
import javax.net.ssl.*; // jdk 1.4 includes ssl in standard distro
/**
* <p>Socket factory for SSL jndi links that returns an SSL socket.
* It incorporates a keystore, which must contain the certs used
* to authenticate the client.</p>
*
* <p>This code is based on sample code made freely available by author
* Spencer W. Thomas on his web site http://hubris.engin.umich.edu/java/
* On Wed 24 May, 2000.</p>
*
* <p><b>Warning</b></p>
*
* <p>This class relies heavily on an internal, single, static SSLSocketFactory.
* multiple objects of this type in fact will use the same internal SSLSocketFactory.
* (This is why a single static init() method sets up everything for the entire
* class.) The reason for this structure is that JndiSocketFactory is dynamically
* invoked by the jndi connection, and we have no other chance to initialise the
* object.</p>
*/
public class JXSSLSocketFactory extends SSLSocketFactory
{
/**
* This is the (static) factory internally shared between
* all JndiSocketFactory objects.
*/
private static SSLSocketFactory factory = null;
/**
* A single default object of this class. It is
* initialised when first called for, and then reused
* whenever called again.
*/
private static JXSSLSocketFactory default_factory = null;
private static KeyStore clientKeystore;
/**
* The sun 'JKS' keystore is the simplest and most commonly
* available keystore type.
*/
private static final String DEFAULT_KEYSTORE_TYPE = "JKS";
/**
* the class loader to use for loading security providers
* 'n stuff. Defaults to the system loader.
*/
private static ClassLoader myClassLoader = null;
/**
* Register a custom class loader to be used by
* the class when getting security providers.
*/
public static void setClassLoader(ClassLoader newLoader)
{
myClassLoader = newLoader;
}
/**
* checks that myClassLoader is initialised, uses the System
* default loader if it isn't, and returns the guaranteed
* initialised loader.
*/
private static ClassLoader getClassLoader()
{
if (myClassLoader == null)
myClassLoader = ClassLoader.getSystemClassLoader();
return myClassLoader;
}
/**
* <p>Enable debugging...</p>
* <P>WARNING - this doesn't seem to be working...??</p>
*/
public static void setDebug(boolean status)
{
/*
all turn on all debugging
ssl turn on ssl debugging
The following can be used with ssl:
record enable per-record tracing
handshake print each handshake message
keygen print key generation data
session print session activity
handshake debugging can be widened with:
data hex dump of each handshake message
verbose verbose handshake message printing
record debugging can be widened with:
plaintext hex dump of record plaintext
*/
if (status == true)
System.setProperty("javax.net.debug", "ssl,handshake,verbose");
else
{
System.setProperty("javax.net.debug", " ");
}
}
/**
* <p>Initialize the socket factory with a particular key store(s) and
* security provider. The minimum requirement is for a keystore
* containing trusted directory servers (the 'castore', or trusted
* certificate authority store, since the servers are usually signed
* by a common CA, whose cert would be held in this file).</p>
*
* <p>Further options include a private key store (the 'clientstore')
* that allows for client-authenticated ssl and SASL).</p>
*
* <p>Finally, it is possible to configure a non-standard keystore
* type and security provider. The keystore type defaults to Sun's
* JKS (at time of writting, the only keystore type that the default
* Sun security provider will handle).</p>
*
* <p>Nb. - it is possible to set a custom class loader (using
* 'registerClassLoader()' ) in which case this loader can be used
* to load the security provider.</p>
*
* @param caKeystoreFile A keystore file name of public certificates (trusted CA signs)
* @param clientKeystoreFile A keystore file name of the client's certificates, containing private keys.
* (may be null if only simple, 'server authenticated' ssl is being used).
* @param caPassphrase A password for the caKeystoreFile certificate.
* (may be null if only simple, 'server authenticated' ssl is being used, and keystore type is 'JKS').
* <b>Calling Program must manually clear passphrase after init() call.</b>
* @param clientPassphrase A password for the clientKeystoreFile certificate.
* (may be null if only simple, 'server authenticated' ssl is being used).
* <b>Calling Program must manually clear passphrase after init() call.</b>
* @param caKeystoreType The type of cakeystore file. (null => 'JKS')
* @param clientKeystoreType The type of clientkeystore file. (null => 'JKS')
* @param owner The owning GUI frame used for possible user interaction.
*/
//
// Implementation note: this may be called repeatedly, with different info,
// as new connections are made. This is unsatisfactory, and dangerous if it
// is being used from multiple threads, but is unavoidable due to the difficulty
// of setting jndi to use a specific SSL socket class (we have to pass it a
// factory). Hence we need to be sure that different calls don't interfere,
// even at the cost of recreating objects unnecessarily...
//
public static void init(String caKeystoreFile, String clientKeystoreFile,
char[] caPassphrase, char[] clientPassphrase,
String caKeystoreType, String clientKeystoreType, Frame owner)
//throws Exception
throws GeneralSecurityException, IOException
{
boolean usingSASL = false; // whether we are using client-authenticated SSL
checkFileSanity(caKeystoreFile, clientKeystoreFile, clientPassphrase);
if ((clientPassphrase!=null) && (clientPassphrase.length>0) && (clientKeystoreFile != null))
usingSASL = true;
// use the client store if there is no caKeystoreFile.
if (caKeystoreFile == null && clientKeystoreFile != null)
caKeystoreFile = clientKeystoreFile;
// set cert authority keystore type to default if required.
if (caKeystoreType == null)
caKeystoreType = DEFAULT_KEYSTORE_TYPE;
// set the ssl protocol - usually "TLS" unless over-ridden
SSLContext sslctx = setSSLContextProtocol();
/*
* The KeyManagerFactory manages the clients certificates *and* private keys,
* which allow the client to authenticate itself to others. It is not required
* for 'simple' SSL, only for SASL.
*/
KeyManagerFactory clientKeyManagerFactory = null;
TrustManagerFactory caTrustManagerFactory = null;
KeyStore caKeystore = null;
KeyManager[] clientKeyManagers = null;
/*
* 'traditional' server-authenticated ssl only requires the use of a trusted server
* keystore. Stronger client-authenticated ssl that requires both parties to authenticate
* (as used in LDAP SASL/External) requires a client keystore with a client private key.
*/
if (usingSASL)
{
/*
* Create a keystore to hold the client certificates and private keys.
*/
if (clientKeystoreType == null)
clientKeystoreType = DEFAULT_KEYSTORE_TYPE;
clientKeystore = KeyStore.getInstance(clientKeystoreType); // key manager key store
/*
* Load the keystore from the client keystore file using the client
* keystore password.
*/
if (clientKeystoreFile != null)
clientKeystore.load(new FileInputStream(clientKeystoreFile), clientPassphrase);
/*
* Create a key manager using the default sun X509 key manager
*/
clientKeyManagerFactory = KeyManagerFactory.getInstance("SunX509");
/*
* Initialise the client keystore manager with the just loaded keystore,
* and the keystore password.
*/
clientKeyManagerFactory.init(clientKeystore, clientPassphrase);
/*
* Initialise the list of key managers
*/
clientKeyManagers = clientKeyManagerFactory.getKeyManagers();
}
else
{
clientKeystore = null;
}
/*
* Initialise the trusted server certificate keystore.
*/
caKeystore = KeyStore.getInstance(caKeystoreType);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -