JDK-6586274 : SSLSocketFactory and SSLServerSocketFactory can't be configured
  • Type: Enhancement
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 6u2
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 2007-07-27
  • Updated: 2010-09-29
  • Resolved: 2009-03-02
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
Tha classes SSLSocketFactory and SSLServerSocketFactory are used to create SSL sockets.  Quite often instances of these factory classes are passed into third-party libraries as a source of sockets.  However, it isn't possible to control the operation of these classes without virtually recreating the entire SSL security provider mechanism, as instances of them can't be created directly - the factories are usually obtained in turn form an instance of SSLContext, which in turn is obtained from a static method (SSLContext.getInstance).

There is already a class (SSLParameters) which can be used to control the behaviour of SSLEngines and individual sockets, via SSLEngine.setSSLParameters and SSLSocket.setSSLParameters.  However there are no corresponding methods on either SSLSocketFactory or SSLServerSocketFactory.  The appropriate getSSLParameters and setSSLParameter methods should be added.

Comments
EVALUATION It is not a have-to-have feature, will not fix it.
02-03-2009

PUBLIC COMMENTS There was so much code in that link, I lost the point of what you were trying to do. Not sure why you'd want to add that much complexity. You have complete control of your SocketFactory. It wraps an existing SSLSocketFactory. Or maybe there's just a simple disconnect in how to do a wrapper SSLSocketFactory? In that main class comment, you say it needs to do the following: * This class provides a mechanism for creating SSL connections for either * client or server use. It uses the specified certificate store as a source * of both the client or server's certificate/key pair, and as a source of * trusted certificates. The underlying certificate store must be in JCEKS * format, and must contain both the application's certificate/private key pair * and any trusted certificates. What I would do is the following: public class MySSLSocketFactory extends SSLSocketFactory { SSLSocketFactory real; // Or pass in some parameters here when creating this thing, such as // an already initialized KeyStore/KMF/TMF's. public MySSLSocketFactory() throws Exception { InputStream stream = // whatever you do; char[] password = // whatever you do; SSLContext sslctx = SSLContext.getInstance("SSLv3"); TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); KeyStore ks = KeyStore.getInstance("JCEKS"); ks.load(stream, password); kmf.init(ks, password); tmf.init(ks); sslctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); real = (SSLSocketFactory) sslctx.getSocketFactory(); } @Override public String[] getDefaultCipherSuites() { String[] r = real.getDefaultCipherSuites(); r.doWhatever(); return r; } @Override public String[] getSupportedCipherSuites() { String[] r = real.getSupportedCipherSuites(); r.doWhatever(); return r; } @Override public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { Socket tmp = real.createSocket(s, host, port, autoClose); tmp.doWhateverYouNeedDone(); return tmp; } etc.etc.
17-02-2009

PUBLIC COMMENTS I think your requirements are: customizing the ssl socket *factories*, so that you can pass the *factory" as a parameter to third parties, and then control or get the consistent behaviors over those sockets created by the *factory*. Am I right on the understanding? Yes, I was talking for the requirements, customizing SSL socket *factory* instead of *socket*, at previous rows. I do think Brad also talked for the same topic. You would think we'd better add a new methods like set/getSSLParameters(), but Brad and I think override those *factories* should be better, different solutions for the same puzzle. I think the ClientAuthServerSocketFactory in your project is a good practice on meeting your requirements. At present, the ssl parameters could be set at two levers, the provider default level and the individual socket level. End users have one and only one place to set the parameters, the individual socket, which make the choice simple. If we add one more level on those *factories*, yes, it does add the flexibility, but it is much hard to make the final choice, and bring more puzzles. For example, If I use a socket created by the parameter SSLSocketFactory, how could I know it is a socket for server or a socket for client?(See SSLSocket.setUseClientMode()). Generally, I have to explicit call setUseClientMode() for sure it is a socket as I wish, the customized parameter does not work as expected, and bring new complexities. So, I don't think it is worthy to introduce the flexibility in the price of such puzzles.
15-02-2009

PUBLIC COMMENTS If you refer back to the original description the issue is not primarily with customising sockets, it is that some libraries (specifically the Apache XML-RPC library) require you pass them a socket *factory* not a socket. And customising a socket *factory* is much more complex that customising a *socket*, requiring you to provide your own provider, amongst other things. See to the code at http://src.opensolaris.org/source/xref/website/auth/AuthSSL/src/org/opensolaris/auth/ssl/SSLSocketManager.java for how I've worked around this. What I'm suggesting in this RFE is that you should be able to provide instances of SSLParameters to the SSL socket factories, and that these would be passed through to the existing method on SSLSocket when sockets are created from the factory. This would allow you to customise the sockets created by the factories without having to recreate the whole provider mechanism. Does that help make what I'm asking for clearer?
14-02-2009

PUBLIC COMMENTS What Xuelei describes is the intended operation. Simple, custom SSLSocketFactory's should be used in the case that the default SSLSocket configuration isn't correct/appropriate. Same with SocketFactory. Custom SSLSocketFactory's allow adjustment of the created Sockets before they are used by the calling application, as Xuelei shows in the previous comment. The original typical use case was tunneling through a firewall. For example: http://www.javaworld.com/javaworld/javatips/jw-javatip111.html Unless there's a use case we're missing, I think this can be closed.
14-02-2009

PUBLIC COMMENTS One can customized socket factories by extending SSLSocketFactory and SSLServerSocketFactory, delegating the call to the provider implementation, customizing individual socket, and then providing the customized factory to 3rd parties. For example: public class MySSLSocketFactory extends SSLSocketFactory { private SSLSocketFactory delegate; private SSLParameters parameters; MySSLSocketFactory(SSLSocketFactory delegate) { this.delegate = delegate; } MySSLSocketFactory(SSLSocketFactory delegate, SSLParamaters parameters) { this.delegate = delegate; this.parameters = parameters; } @override public Socket createSocket(String host, int port) { SSLSocket socket = (SSLSocket)delegate,create(host, port); socket.setSSLParameters(parameters); return socket; } } Is it acceptable?
13-02-2009

PUBLIC COMMENTS There are already configurable SSL parameters on individual SSL socket or engine. In the level of SSLContext, SSLSocketFactory and SSLServerSocketFactory, it would be better to keep it simple and do not touch too much on individual SSL parameters. Now, there are APIs defined to get the necessary parameters default or supported by provider, and one always can configure individual socket/engine, it is not a have-to-have feature, will not fix it.
12-02-2009

PUBLIC COMMENTS Sorry, I don't follow the previous comment. I can't find any way of passing configuration to a provider, and as I said originally, if you are providing a factory to a 3rd party library there is no way of setting the parameters on the sockets that come out of that factory. If I'm misunderstanding, could you illustrate with some code how this might be done? Thanks,
12-02-2009