//*****************************************************************************
//*
//* (c) Copyright 2002. Glub Tech, Incorporated. All Rights Reserved.
//*
//* $Id: SSLTrustManager.java 37 2009-05-11 22:46:15Z gary $
//*
//*****************************************************************************
package com.glub.secureftp.bean;
import com.glub.secureftp.common.*;
import com.glub.util.*;
import java.io.*;
import java.net.*;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
/**
* This handles the trust issues for the SSL certs.
*/
public class SSLTrustManager implements X509TrustManager {
private TrustManager defaultTM = null;
private SSLKeyStore sslKeyStore = null;
private SSLSessionManager sslSessionManager = null;
private InetAddress serverAddress = null;
private OutputStreamWriter replyStreamWriter = null;
private KeyStore tempKeyStore = null;
private boolean certTrusted = false;
/** Debug output */
private boolean debug = GTOverride.getBoolean("glub.debug");
public SSLTrustManager( SSLKeyStore sslKeyStore,
SSLSessionManager sslSessionManager,
InetAddress serverAddress,
OutputStream replyStream )
throws IllegalArgumentException {
if ( sslKeyStore == null ) {
throw new IllegalArgumentException("ssl key store cannot be null");
}
else if ( sslSessionManager == null ) {
throw new IllegalArgumentException("ssl session mgr cannot be null");
}
this.sslKeyStore = sslKeyStore;
this.sslSessionManager = sslSessionManager;
this.serverAddress = serverAddress;
try {
TrustManagerFactory defaultTMF =
// TrustManagerFactory.getInstance("SunX509", "SunJSSE");
TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() );
defaultTMF.init((java.security.KeyStore)null);
defaultTM = defaultTMF.getTrustManagers()[0];
}
catch ( Exception e ) {}
if ( replyStream != null ) {
replyStreamWriter = new OutputStreamWriter(replyStream);
}
try {
char[] tempPass = (new String("temP")).toCharArray();
tempKeyStore = KeyUtil.getKeyStore(tempPass);
}
catch ( Exception e ) {}
}
public X509Certificate[] getAcceptedIssuers() {
// not yet implemented
return null;
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
boolean checkIt = true;
try {
if ( null != defaultTM ) {
((X509TrustManager)defaultTM).checkServerTrusted(chain, authType);
X509Certificate cert = chain[0];
SSLCertificate sslCert = new SSLCertificate( cert );
sslSessionManager.setCurrentCertificate( sslCert );
checkIt = false;
}
}
catch ( Exception e ) {}
boolean throwIt = checkIt;
if ( checkIt ) {
throwIt = !isServerTrusted(chain);
}
if ( throwIt ) {
throw new CertificateException("Untrusted Server Certificate Chain");
}
}
public boolean isServerTrusted(X509Certificate[] chain) {
boolean trustIt = false;
if ( debug )
System.out.println( "Checking if server is trusted" );
if ( certTrusted ) {
return true;
}
try {
if ( chain == null || chain.length < 1 || chain[0] == null ) {
certTrusted = sslSessionManager.continueWithoutServerCertificate();
return certTrusted;
}
X509Certificate cert = chain[0];
SSLCertificate sslCert = new SSLCertificate( cert );
sslSessionManager.setCurrentCertificate( sslCert );
try {
cert.checkValidity();
}
catch ( CertificateExpiredException cee ) {
certTrusted = sslSessionManager.continueWithExpiredCertificate( sslCert );
return certTrusted;
}
// if we have a server's address make sure it matches the certificates
if ( serverAddress != null ) {
String hostName = serverAddress.getHostName();
String hostAddr = serverAddress.getHostAddress();
if ( hostName == null ) {
hostName = "";
}
if ( !sslCert.getCN().equalsIgnoreCase(hostName) &&
!sslCert.getCN().equals(hostAddr) ) {
certTrusted =
sslSessionManager.continueWithCertificateHostMismatch(sslCert,
hostName,
sslCert.getCN());
return certTrusted;
}
}
// check the keystore for the certificate
if ( KeyUtil.certificateExists(sslKeyStore.getKeyStore(), cert) ) {
trustIt = true;
}
else if ( KeyUtil.certificateExists(tempKeyStore, cert) ) {
trustIt = true;
}
else {
short whatToDo = SSLSessionManager.DENY_CERTIFICATE;
X509Certificate oldCert = null;
if ( KeyUtil.certificateAliasExists(sslKeyStore.getKeyStore(), cert) ) {
String alias = cert.getSubjectDN().toString();
oldCert =
(X509Certificate)sslKeyStore.getKeyStore().getCertificate(alias);
SSLCertificate oldSslCert = new SSLCertificate(oldCert);
whatToDo = sslSessionManager.replaceCertificate(oldSslCert, sslCert);
}
else {
whatToDo = sslSessionManager.newCertificateEncountered(sslCert);
}
switch ( whatToDo ) {
case SSLSessionManager.ALLOW_CERTIFICATE:
trustIt = true;
KeyUtil.addCertificate( tempKeyStore, cert );
break;
case SSLSessionManager.SAVE_CERTIFICATE:
trustIt = true;
try {
if ( oldCert != null ) {
KeyUtil.removeCertificate(sslKeyStore.getKeyStore(), oldCert);
}
KeyUtil.addCertificate( sslKeyStore.getKeyStore(), cert );
if ( null != sslKeyStore.getKeyStoreFile() ) {
KeyUtil.writeKeyStore( sslKeyStore.getKeyStore(),
sslKeyStore.getKeyStoreFile(),
sslKeyStore.getKeyStorePass() );
}
else if ( null != replyStreamWriter ) {
replyStreamWriter.write("The key store file is not valid.");
replyStreamWriter.write(System.getProperty("line.separator"));
replyStreamWriter.flush();
}
}
catch ( Exception e ) {
if ( null != replyStreamWriter ) {
replyStreamWriter.write(e.getMessage());
replyStreamWriter.write(System.getProperty("line.separator"));
replyStreamWriter.flush();
}
}
break;
case SSLSessionManager.DENY_CERTIFICATE:
default:
trustIt = false;
break;
}
}
}
catch ( Exception e ) {
trustIt = false;
}
if ( debug )
System.out.println( "Trust server: " + trustIt );
certTrusted = trustIt;
return certTrusted;
}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
if ( !isClientTrusted(chain) ) {
throw new CertificateException("Untrusted Client Certificate Chain");
}
}
public boolean isClientTrusted(X509Certificate[] chain) {
// not used in client
return true;
}
}