I'd like to know how I can implement a server socket to let it able to identify and use correct certificate according with the certificate being used by client to proceed handshake communication with the server.
Explaining better, in the server side is:
AppServerSideSocket.jar
- private keystore: privateKeyApp (type JKS, generated with keytool)
- public keystore : publicKeyApp (type JKS, shared with all clients)
And in the client side ...
AppClientSideSocket.jar - public keystore : publicKeyApp
The AppServerSideSocket.jar listening clients requests and once received proocess information sent by clients
The AppClientSideSocket.jar connect with the server using SSL using publicKeyApp without verify server hostname and after handshake send information for the AppServerSideSocket application.
Now I've another client application, AppClientSideSocketNEW.jar, and this verify server hostname to make communication with the server. In this case, the CN used in the public certificate on the client side must be match with the hostname where AppServerSideSocket.jar are.
Originaly the connection was configured in this way on the server side:
if (usingSSLConn) {
System.setProperty("javax.net.ssl.keyStore", "privateKeyApp");
System.setProperty("javax.net.ssl.keyStorePassword", "privateKeyAppPassword");
SSLServerSocketFactory sslServerSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
ServerSocket serverSocketApp = sslServerSocketFactory.createServerSocket(Port);
} else
serverSocketApp = new ServerSocket(Port);
}
All the clients received the same publicKeyApp and connect with the server without verify hostname, so doesn't matter if the server where server socket application (AppServerSideSocket.jar) is installed in the server with hostname is badServer1.com and the CN of key in privateKeyApp and publicKeyApp is setted with goodServer1.com, because all the clients don't verify hostname or the CN attribute of the key.
Bellow is showed a piece of this kind of connection:
private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
System.setProperty("javax.net.ssl.trustStore", publicKey1);
System.getProperties().setProperty("java.protocol.handler.pkgs",
"javax.net.ssl.internal.www.protocol");
HttpsURLConnection.setDefaultHostnameVerifier(DO_NOT_VERIFY);
...
SOAPConnectionFactory soapConn = SOAPConnectionFactory.newInstance();
SOAPConnection connection = soapConn.createConnection();
...
URL endpoint = new URL(hostname + ":" + port);
But the new client (AppClientSideSocketNEW.jar) do this verification obrigatorily, now is necessary provide a new certificate for this client with new value for CN attribute reflecting the correct hostname CN where the server socket is.
I don't have access to second client and I'm sure that it do hostname verification.
So I created two new key-pair ceritificates (privateKeyAppNew and publicKeyAppNew) and aparently the communications happened with success between the server using this new key-pair and new client using this new public publicKeyAppNew key.
But I need continue to use the old key-pair for old clients. I'd like to know how can I deal with this.
Using a keymanager let me able to verify the client certificate on the server app when client try to connect and choose the apropriate and do the handshake using the correct certificate?
Or I need disctinct ssl socket connection in different ports for which kind of clients?