//*****************************************************************************
//*
//* (c) Copyright 2002. Glub Tech, Incorporated. All Rights Reserved.
//*
//* $Id: SSLUtil.java 109 2009-11-25 06:27:28Z gary $
//*
//*****************************************************************************
package com.glub.secureftp.common;
import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;
import java.util.regex.*;
import javax.net.ssl.*;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
//import com.sun.net.ssl.*;
public class SSLUtil
{
// Class constants
private static final String SSL_PROTOCOL = "TLS";
//private static final String SSL_PROVIDER = "SunJSSE";
private static String[] enabledCipherSuites = null;
/*
static {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
}
*/
private static String[] getEnabledCipherSuites( String[] oldCipherOrder ) {
if ( enabledCipherSuites == null ) {
enabledCipherSuites = getSupportedCiphers( oldCipherOrder );
}
return enabledCipherSuites;
}
public static SSLServerSocket createServerSocket( int port,
int backlog,
String host,
SSLServerSocketFactory f )
throws IOException, UnknownHostException
{
ServerSocket ss = null;
if (f != null) {
ss = f.createServerSocket( port,
backlog,
InetAddress.getByName( host ) );
}
else {
return null;
}
String oldCipherOrder[] = ((SSLServerSocket)ss).getSupportedCipherSuites();
//String oldCipherOrder[] = ((SSLServerSocket)ss).getEnabledCipherSuites();
((SSLServerSocket)ss).setEnabledCipherSuites( getEnabledCipherSuites(oldCipherOrder) );
return (SSLServerSocket)ss;
}
// autoClose set to false will leave the oldSock open even when the new
// one is closed (useful for CCC)
public static SSLSocket createSocket( Socket oldSock, String addr, int port,
SSLSocketFactory f, boolean autoClose )
throws IOException
{
Socket s = null;
if (f != null) {
s = f.createSocket( oldSock, addr, port, autoClose );
}
String oldCipherOrder[] = ((SSLSocket)s).getSupportedCipherSuites();
//String oldCipherOrder[] = ((SSLSocket)s).getEnabledCipherSuites();
((SSLSocket)s).setEnabledCipherSuites( getEnabledCipherSuites(oldCipherOrder) );
return (SSLSocket)s;
}
public static SSLSocket createSocket( Socket oldSock, String addr, int port,
SSLSocketFactory f )
throws IOException
{
return createSocket( oldSock, addr, port, f, true );
}
public static SSLSocket createSocket( String addr, int port,
SSLSocketFactory f )
throws IOException
{
return createSocket( new Socket(addr, port), addr, port, f );
}
public static SSLContext getContext( KeyManager[] km,
TrustManager[] tm,
SecureRandom random )
throws KeyManagementException
{
SSLContext context = null;
try {
//context = SSLContext.getInstance( SSL_PROTOCOL, SSL_PROVIDER );
context = SSLContext.getInstance( SSL_PROTOCOL );
context.init( km, tm, random );
}
catch (NoSuchAlgorithmException nsae) {
// Leave context as null
}
/*
catch (NoSuchProviderException nspe) {
// Leave context as null
}
*/
return context;
}
public static SSLSocketFactory getSocketFactory( SSLContext c )
{
SSLSocketFactory factory = null;
if (c != null) {
factory = (SSLSocketFactory)c.getSocketFactory();
}
return factory;
}
public static SSLServerSocketFactory getServerSocketFactory( SSLContext c )
{
SSLServerSocketFactory factory = null;
if (c != null) {
factory = (SSLServerSocketFactory)c.getServerSocketFactory();
}
return factory;
}
private static String[] getSupportedCiphers( String ciphers[] ) {
Pattern pattern256AES = Pattern.compile( "AES.256" );
Pattern pattern128AES = Pattern.compile( "AES.128" );
Pattern pattern3DES = Pattern.compile( "3DES" );
Matcher matcher;
boolean matchFound;
int len = ciphers.length;
ArrayList list256AES = new ArrayList();
ArrayList list128AES = new ArrayList();
ArrayList list3DES = new ArrayList();
ArrayList listOthers = new ArrayList();
for (int i = 0; i < len; i++) {
// we won't accept anything using md5 (FIPS compliancy)
if ( ciphers[i].toLowerCase().endsWith("md5") )
continue;
// determine if pattern exists in input
matcher = pattern256AES.matcher( ciphers[i] );
matchFound = matcher.find();
if ( matchFound ) {
list256AES.add( ciphers[i] );
}
else {
matcher = pattern128AES.matcher( ciphers[i] );
matchFound = matcher.find();
if ( matchFound ) {
list128AES.add( ciphers[i] );
}
else {
matcher = pattern3DES.matcher( ciphers[i] );
matchFound = matcher.find();
if ( matchFound ) {
list3DES.add( ciphers[i] );
}
else {
//listOthers.add( ciphers[i] );
}
}
}
}
String set[] = new String[list256AES.size() + list128AES.size() + list3DES.size() + listOthers.size()];
int j = 0;
for ( int k = 0; k < list256AES.size(); k++ ) {
set[j++] = (String)list256AES.get( k );
}
for ( int l = 0; l < list128AES.size(); l++ ) {
set[j++] = (String)list128AES.get( l );
}
for ( int m = 0; m < list3DES.size(); m++ ) {
set[j++] = (String)list3DES.get( m );
}
for ( int n = 0; n < listOthers.size(); n++ ) {
set[j++] = (String)listOthers.get( n );
}
return set;
}
}