Skip to Main Content

Java Security

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

How to use custom truststore?

843811Feb 23 2007 — edited Aug 7 2008
Hi, I've written a simple ssl client (basing on jakarta commons httpclient project) that connects to IIS with SSL and it works only i f I add ssl certificate from IIS to the jre cacerts (using keytool import). The cacerts are automatically readed somehow (don't know how)
I want to make the whole thing more elastic and be able to provide my client with a path to cacerts / truststore / keystore. Am I doing it OK? I Currently it works...

BUT the loops that print certificates and trustores to screen are empty - for example keystore .getCertificateChain(alias); always returns null....

But IIS cert is inside
C:\\Program Files\\Java\\jre1.5.0_09\\lib\\security\\cacertsbbb


PS. I would like to avoid setting System properties in my code like System.setTruststore etc.
PS. Should be without sockets. Just extension of what i got.
 

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.log4j.Logger;

import junit.framework.TestCase;

public class SSLSocketClient extends TestCase {

	private URL keystoreUrl = null;

	private String mockKeystoreUrl = "C:\\Program Files\\Java\\jre1.5.0_09\\lib\\security\\cacertsbbb";

	private String keystorePassword = "changeit";

	private URL truststoreUrl = null;

	private String mockTruststoreUrl = "C:\\Program Files\\Java\\jre1.5.0_09\\lib\\security\\cacertsbbb";

	private String truststorePassword = null;

	private SSLContext sslcontext = null;
	
	//

	public void testSSLSocket() {
		try {
			SSLSocketClient client = new SSLSocketClient();

			// client.createSocket("10.63.29.50", 443);

			HttpConnectionParams params = new HttpConnectionParams();
			InetAddress ia = InetAddress.getLocalHost();
			// params.setParameter(arg0, arg1)

			//client.createSocket("10.63.29.50", 443, ia, 444, params);
			
			client.connect("10.63.29.50", 443, "/ssl2/index.html", params);
		} catch (ConnectTimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private static Logger log = Logger.getLogger(SSLSocketClient.class);

	/*
	 * private static KeyStore createKeyStore(final URL url, final String
	 * password) throws KeyStoreException, NoSuchAlgorithmException,
	 * CertificateException, IOException { if (url == null) { throw new
	 * IllegalArgumentException("Keystore url may not be null"); }
	 * 
	 * KeyStore keystore = KeyStore.getInstance("jks");
	 * keystore.load(url.openStream(), password != null ? password
	 * .toCharArray() : null); return keystore; }
	 */

	private KeyStore mockCreateKeyStore(final String url, final String password)
			throws KeyStoreException, NoSuchAlgorithmException,
			CertificateException, IOException {
		if (url == null) {
			throw new IllegalArgumentException("Keystore url may not be null");
		}
		InputStream keystoreStream = new FileInputStream(url);

		KeyStore keystore = KeyStore.getInstance("jks");
		keystore.load(keystoreStream, password != null ? password.toCharArray()
				: null);
		return keystore;
	}

	private KeyManager[] createKeyManagers(final KeyStore keystore,
			final String password) throws KeyStoreException,
			NoSuchAlgorithmException, UnrecoverableKeyException {
		if (keystore == null) {
			throw new IllegalArgumentException("Keystore may not be null");
		}

		KeyManagerFactory kmfactory = KeyManagerFactory
				.getInstance(KeyManagerFactory.getDefaultAlgorithm());
		kmfactory.init(keystore, password != null ? password.toCharArray()
				: null);
		return kmfactory.getKeyManagers();
	}

	private TrustManager[] createTrustManagers(final KeyStore keystore)
			throws KeyStoreException, NoSuchAlgorithmException {
		if (keystore == null) {
			throw new IllegalArgumentException("Keystore may not be null");
		}

		TrustManagerFactory tmfactory = TrustManagerFactory
				.getInstance(TrustManagerFactory.getDefaultAlgorithm());
		tmfactory.init(keystore);
		TrustManager[] trustmanagers = tmfactory.getTrustManagers();
		for (int i = 0; i < trustmanagers.length; i++) {
			if (trustmanagers[i] instanceof X509TrustManager) {
				trustmanagers[i] = new AuthSSLX509TrustManager(
						(X509TrustManager) trustmanagers);
}
}
return trustmanagers;
}

private SSLContext createSSLContext() {
try {
KeyManager[] keymanagers = null;
TrustManager[] trustmanagers = null;
if (this.mockKeystoreUrl != null) {
KeyStore keystore = mockCreateKeyStore(this.mockKeystoreUrl,
this.keystorePassword);
//if (log.isDebugEnabled()) {
Enumeration aliases = keystore.aliases();
while (aliases.hasMoreElements()) {
String alias = (String) aliases.nextElement();
Certificate[] certs = keystore
.getCertificateChain(alias);
if (certs != null) {
log.info("Certificate chain '" + alias + "':");
for (int c = 0; c < certs.length; c++) {
if (certs[c] instanceof X509Certificate) {
X509Certificate cert = (X509Certificate) certs[c];
log.info(" Certificate " + (c + 1) + ":");
log.info(" Subject DN: "
+ cert.getSubjectDN());
log.info(" Signature Algorithm: "
+ cert.getSigAlgName());
log.info(" Valid from: "
+ cert.getNotBefore());
log.info(" Valid until: "
+ cert.getNotAfter());
log
.info(" Issuer: "
+ cert.getIssuerDN());
}
}
}
}
//}
keymanagers = createKeyManagers(keystore, this.keystorePassword);
}
if (this.mockTruststoreUrl != null) {
KeyStore keystore = mockCreateKeyStore(this.mockKeystoreUrl,
this.truststorePassword);
//if (log.isDebugEnabled()) {
Enumeration aliases = keystore.aliases();
while (aliases.hasMoreElements()) {
String alias = (String) aliases.nextElement();
log.debug("Trusted certificate '" + alias + "':");
Certificate trustedcert = keystore
.getCertificate(alias);
if (trustedcert != null
&& trustedcert instanceof X509Certificate) {
X509Certificate cert = (X509Certificate) trustedcert;
log.info(" Subject DN: " + cert.getSubjectDN());
log.info(" Signature Algorithm: "
+ cert.getSigAlgName());
log.info(" Valid from: " + cert.getNotBefore());
log.info(" Valid until: " + cert.getNotAfter());
log.info(" Issuer: " + cert.getIssuerDN());
}
}
//}
trustmanagers = createTrustManagers(keystore);
}
SSLContext sslcontext = SSLContext.getInstance("SSL");
// /sslcontext.
sslcontext.init(keymanagers, trustmanagers, null);
return sslcontext;
} catch (NoSuchAlgorithmException e) {
log.error(e.getMessage(), e);
throw new RuntimeException("Unsupported algorithm exception: "
+ e.getMessage());
// throw new AuthSSLInitializationError("Unsupported algorithm
// exception: " + e.getMessage());
} catch (KeyStoreException e) {
log.error(e.getMessage(), e);
throw new RuntimeException("Keystore exception: " + e.getMessage());
// throw new AuthSSLInitializationError("Keystore exception: " +
// e.getMessage());
} catch (GeneralSecurityException e) {
log.error(e.getMessage(), e);
throw new RuntimeException("Key management exception: "
+ e.getMessage());
// throw new AuthSSLInitializationError("Key management exception: "
// + e.getMessage());
} catch (IOException e) {
log.error(e.getMessage(), e);
throw new RuntimeException(
"I/O error reading keystore/truststore file: "
+ e.getMessage());
// throw new AuthSSLInitializationError("I/O error reading
// keystore/truststore file: " + e.getMessage());
}
}

private SSLContext getSSLContext() {
if (this.sslcontext == null) {
this.sslcontext = createSSLContext();
}
return this.sslcontext;
}

/**
* Attempts to get a new socket connection to the given host within the
* given time limit.
* <p>
* To circumvent the limitations of older JREs that do not support connect
* timeout a controller thread is executed. The controller thread attempts
* to create a new socket within the given limit of time. If socket
* constructor does not return until the timeout expires, the controller
* terminates and throws an {@link ConnectTimeoutException}
* </p>
*
* @param host
* the host name/IP
* @param port
* the port on the host
* @param clientHost
* the local host name/IP to bind the socket to
* @param clientPort
* the port on the local machine
* @param params
* {@link HttpConnectionParams Http connection parameters}
*
* @return Socket a new socket
* @throws IOException
* @throws IOException
* if an I/O error occurs while creating the socket
* @throws UnknownHostException
* if the IP address of the host cannot be determined
*/

public void connect(final String host, final int sport, final String query,
final HttpConnectionParams params) throws IOException {

HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String arg0, SSLSession arg1) {
System.out.println("Bartek: Hostname is not matched for cert.");
return true;
}
};
URL wlsUrl = null;

wlsUrl = new URL("https", host, Integer.valueOf(sport).intValue(),
query);
System.out
.println(" Trying a new HTTPS connection using WLS client classes - "
+ wlsUrl.toString());
HttpsURLConnection sconnection = (HttpsURLConnection) wlsUrl
.openConnection();
SocketFactory socketfactory = getSSLContext().getSocketFactory();
/*
* HttpsURLConnection sconnection = new HttpsURLConnection( wlsUrl);
*/
sconnection.setHostnameVerifier(hv);
//sconnection.setSSLSocketFactory((SSLSocketFactory) socketfactory);
sconnection.setSSLSocketFactory((SSLSocketFactory) socketfactory);

//sconnection.setHostnameVerifier(hv);

tryConnection(sconnection, System.out);
}

public static void tryConnection(HttpsURLConnection connection,
OutputStream stream) throws IOException {
connection.connect();

String responseStr = "\t\t" + connection.getResponseCode() + " -- "
+ connection.getResponseMessage() + "\n\t\t"
+ connection.getContent().getClass().getName() + "\n";
connection.disconnect();
System.out.print(responseStr);
}


}




Message was edited by:
herbatniczek
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Apr 29 2007
Added on Feb 23 2007
2 comments
1,149 views