Return-Path: Delivered-To: apmail-jakarta-tomcat-dev-archive@apache.org Received: (qmail 67475 invoked from network); 11 Jul 2003 01:05:55 -0000 Received: from exchange.sun.com (192.18.33.10) by daedalus.apache.org with SMTP; 11 Jul 2003 01:05:55 -0000 Received: (qmail 28440 invoked by uid 97); 11 Jul 2003 01:08:27 -0000 Delivered-To: qmlist-jakarta-archive-tomcat-dev@nagoya.betaversion.org Received: (qmail 28433 invoked from network); 11 Jul 2003 01:08:27 -0000 Received: from daedalus.apache.org (HELO apache.org) (208.185.179.12) by nagoya.betaversion.org with SMTP; 11 Jul 2003 01:08:27 -0000 Received: (qmail 63912 invoked by uid 500); 11 Jul 2003 01:04:57 -0000 Mailing-List: contact tomcat-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Tomcat Developers List" Reply-To: "Tomcat Developers List" Delivered-To: mailing list tomcat-dev@jakarta.apache.org Received: (qmail 63880 invoked by uid 500); 11 Jul 2003 01:04:56 -0000 Received: (qmail 63863 invoked from network); 11 Jul 2003 01:04:56 -0000 Received: from icarus.apache.org (208.185.179.13) by daedalus.apache.org with SMTP; 11 Jul 2003 01:04:56 -0000 Received: (qmail 96238 invoked by uid 1399); 11 Jul 2003 01:04:55 -0000 Date: 11 Jul 2003 01:04:55 -0000 Message-ID: <20030711010455.96237.qmail@icarus.apache.org> From: luehe@apache.org To: jakarta-tomcat-connectors-cvs@apache.org Subject: cvs commit: jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse JSSE14SocketFactory.java JSSESocketFactory.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N luehe 2003/07/10 18:04:54 Modified: util/java/org/apache/tomcat/util/net/jsse JSSE14SocketFactory.java JSSESocketFactory.java Log: Added support for enabling subset of supported SSL cipher suites (based on earlier proposal) Revision Changes Path 1.3 +29 -60 jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14SocketFactory.java Index: JSSE14SocketFactory.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSE14SocketFactory.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- JSSE14SocketFactory.java 15 Mar 2003 07:00:07 -0000 1.2 +++ JSSE14SocketFactory.java 11 Jul 2003 01:04:54 -0000 1.3 @@ -60,10 +60,8 @@ import java.io.*; import java.net.*; - import java.security.KeyStore; - -import java.security.Security; +import java.security.SecureRandom; import javax.net.ServerSocketFactory; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLSocket; @@ -99,82 +97,53 @@ super(); } - // -------------------- Internal methods - /** Read the keystore, init the SSL socket factory + /** + * Reads the keystore and initializes the SSL socket factory. */ - void initProxy() throws IOException { + void init() throws IOException { try { - // Please don't change the name of the attribute - other - // software may depend on it ( j2ee for sure ) - String keystoreFile=(String)attributes.get("keystore"); - if( keystoreFile==null) keystoreFile=defaultKeystoreFile; - - keystoreType=(String)attributes.get("keystoreType"); - if( keystoreType==null) keystoreType=defaultKeystoreType; - - //determine whether we want client authentication - // the presence of the attribute enables client auth - String clientAuthStr=(String)attributes.get("clientauth"); - if(clientAuthStr != null){ - if(clientAuthStr.equals("true")){ - clientAuth=true; - } else if(clientAuthStr.equals("false")) { - clientAuth=false; - } else { - throw new IOException("Invalid value '" + - clientAuthStr + - "' for 'clientauth' parameter:"); - } - } - - String keyPass=(String)attributes.get("keypass"); - if( keyPass==null) keyPass=defaultKeyPass; + String clientAuthStr = (String)attributes.get("clientauth"); + if (clientAuthStr != null){ + clientAuth = Boolean.valueOf(clientAuthStr).booleanValue(); + } - String keystorePass=(String)attributes.get("keystorePass"); - if( keystorePass==null) keystorePass=keyPass; - - //protocol for the SSL ie - TLS, SSL v3 etc. + // SSL protocol variant (e.g., TLS, SSL v3, etc.) String protocol = (String)attributes.get("protocol"); - if(protocol == null) protocol = defaultProtocol; - - //Algorithm used to encode the certificate ie - SunX509 + if (protocol == null) protocol = defaultProtocol; + + // Certificate encoding algorithm (e.g., SunX509) String algorithm = (String)attributes.get("algorithm"); - if(algorithm == null) algorithm = defaultAlgorithm; - - // You can't use ssl without a server certificate. - // Create a KeyStore ( to get server certs ) - KeyStore kstore = initKeyStore( keystoreFile, keystorePass ); - - SSLContext context = SSLContext.getInstance(protocol); //SSL + if (algorithm == null) algorithm = defaultAlgorithm; - // Key manager will extract the server key + // Set up KeyManager, which will extract server key KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); - kmf.init( kstore, keyPass.toCharArray()); + String keystoreType = (String)attributes.get("keystoreType"); + if (keystoreType == null) + keystoreType = defaultKeystoreType; + String keystorePass = getKeystorePassword(); + kmf.init(getKeystore(keystoreType, keystorePass), + keystorePass.toCharArray()); - // set up TrustManager + // Set up TrustManager TrustManager[] tm = null; - String trustStoreFile = System.getProperty("javax.net.ssl.trustStore"); - String trustStorePassword = - System.getProperty("javax.net.ssl.trustStorePassword"); - if ( trustStoreFile != null && trustStorePassword != null ){ - KeyStore trustStore = - initKeyStore( trustStoreFile, trustStorePassword); - + KeyStore trustStore = getTrustStore(keystoreType); + if (trustStore != null) { TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(trustStore); tm = tmf.getTrustManagers(); } - // init context with the key managers - context.init(kmf.getKeyManagers(), tm, - new java.security.SecureRandom()); + // Create and init SSLContext + SSLContext context = SSLContext.getInstance(protocol); + context.init(kmf.getKeyManagers(), tm, new SecureRandom()); // create proxy sslProxy = context.getServerSocketFactory(); - return; + // Determine which cipher suites to enable + enabledCiphers = getEnabledCiphers(sslProxy.getSupportedCipherSuites()); + } catch(Exception e) { if( e instanceof IOException ) throw (IOException)e; 1.3 +212 -136 jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java Index: JSSESocketFactory.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- JSSESocketFactory.java 15 Mar 2003 06:55:21 -0000 1.2 +++ JSSESocketFactory.java 11 Jul 2003 01:04:54 -0000 1.3 @@ -60,10 +60,10 @@ import java.io.*; import java.net.*; - +import java.util.Vector; import java.security.KeyStore; - import java.security.Security; +import java.security.SecureRandom; import javax.net.ServerSocketFactory; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLSocket; @@ -92,31 +92,29 @@ public class JSSESocketFactory extends org.apache.tomcat.util.net.ServerSocketFactory { - String keystoreType; - - static String defaultKeystoreType = "JKS"; + // defaults static String defaultProtocol = "TLS"; static String defaultAlgorithm = "SunX509"; static boolean defaultClientAuth = false; + static String defaultKeystoreType = "JKS"; + private static final String defaultKeystoreFile + = System.getProperty("user.home") + "/.keystore"; + private static final String defaultKeyPass = "changeit"; + + protected boolean initialized; + protected boolean clientAuth = false; + protected SSLServerSocketFactory sslProxy = null; + protected String[] enabledCiphers; + - boolean clientAuth = false; - SSLServerSocketFactory sslProxy = null; - - // defaults - static String defaultKeystoreFile=System.getProperty("user.home") + - "/.keystore"; - static String defaultKeyPass="changeit"; - - public JSSESocketFactory () { } public ServerSocket createSocket (int port) throws IOException { - if( sslProxy == null ) initProxy(); - ServerSocket socket = - sslProxy.createServerSocket(port); + if (!initialized) init(); + ServerSocket socket = sslProxy.createServerSocket(port); initServerSocket(socket); return socket; } @@ -124,9 +122,8 @@ public ServerSocket createSocket (int port, int backlog) throws IOException { - if( sslProxy == null ) initProxy(); - ServerSocket socket = - sslProxy.createServerSocket(port, backlog); + if (!initialized) init(); + ServerSocket socket = sslProxy.createServerSocket(port, backlog); initServerSocket(socket); return socket; } @@ -135,96 +132,216 @@ InetAddress ifAddress) throws IOException { - if( sslProxy == null ) initProxy(); - ServerSocket socket = - sslProxy.createServerSocket(port, backlog, ifAddress); + if (!initialized) init(); + ServerSocket socket = sslProxy.createServerSocket(port, backlog, + ifAddress); initServerSocket(socket); return socket; } - - // -------------------- Internal methods - /** Read the keystore, init the SSL socket factory - */ - void initProxy() throws IOException { + public Socket acceptSocket(ServerSocket socket) + throws IOException + { + SSLSocket asock = null; try { - Security.addProvider (new sun.security.provider.Sun()); - Security.addProvider (new com.sun.net.ssl.internal.ssl.Provider()); + asock = (SSLSocket)socket.accept(); + asock.setNeedClientAuth(clientAuth); + } catch (SSLException e){ + throw new SocketException("SSL handshake error" + e.toString()); + } + return asock; + } + + public void handshake(Socket sock) throws IOException { + ((SSLSocket)sock).startHandshake(); + } + + /* + * Determines the SSL cipher suites to be enabled. + * + * @return Array of SSL cipher suites to be enabled, or null if the + * cipherSuites property was not specified (meaning that all supported + * cipher suites are to be enabled) + */ + protected String[] getEnabledCiphers(String[] supportedCiphers) { + + String[] enabledCiphers = null; + + String attrValue = (String)attributes.get("ciphers"); + if (attrValue != null) { + Vector vec = null; + int fromIndex = 0; + int index = attrValue.indexOf(',', fromIndex); + while (index != -1) { + String cipher = attrValue.substring(fromIndex, index).trim(); + /* + * Check to see if the requested cipher is among the supported + * ciphers, i.e., may be enabled + */ + for (int i=0; supportedCiphers != null + && i