I am trying to create an SSL Socket Server / Client between .NET and Java. In this case, my Socket SSL server will work in .net, and the client runs on Java under Linux. My problem is that the connection fails during the connection establishment, especially when the server requests a certificate from the client, the client cannot send something back and the connection does not work.
In .net I use sslStream to establish a connection, and in Java I use standard SSLSocket. Below are some snippets of code, but this is what I still have:
On the server side (Windows), I have a private certificate in the Personal / Certificates folders in the MMC. I have an open certificate from a client in trusted persons / certificates. Both certificates were issued by the same CA. The certificate chain for both certificates has several levels, but it is the same for both. The root-level certificate in the chain is also installed in the trusted certificates / certificates folder.
On the client side (Linux), I have a keystore that contains a private certificate that matches the public certificate installed on the server. I have a trust store that contains a public certificate from the server corresponding to the private server.
On the server side (.net), I use Socket, which performs asynchronous reading, and then it ends in SSLStream, the code fragment looks like this:
NetworkStream ns = new NetworkStream(socket, false); SslStream ssl = new SslStream(ns, true); ssl.AuthenticateAsServer(serverCertificate, true, SslProtocols.Default, true);
Client code is pretty much standard code:
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); InetAddress addr = InetAddress.getByName(servername); SSLSocket socket = (SSLSocket) factory.createSocket(addr,port); socket.setUseClientMode(true); socket.setNeedClientAuth(true); socket.setWantClientAuth(true); socket.startHandshake(); os = new DataOutputStream(socket.getOutputStream()); is = new DataInputStream(socket.getInputStream()); byte[] outBuf = new byte[50]; os.write("SEND SOMETHING".getBytes("UTF-8")); is.read(outBuf);
In java, I installed the correct varialbes to indicate trust and keystore with their password.
Now, following the SSL Handshake standard, here's what happens:
- Clienthello
- Serverhello
- The server sends a public certificate
- The client maps the public certificate to that in the trust store
- Server sends certificate request
- With a certificate request, the server sends a list of valid CAs, in this list only my root CA is sent (among a long list of other known CAs.).
- The client certificate is null.
- The server receives a null certificate from the client, thereby closing the connection.
And here it is, the client will not send a valid certificate back to the server. I have some questions about this:
Has anyone experienced something like this? Regarding this list of CAs sent by the server (Windows), how does .net determine what to send to the client? Is there any way to change this list? Do I need to send all the authority in the chain used to sign my certificate in this list of certificate authorities? or is root enough?
Am I missing something on either side of my code?
Any help would be greatly appreciated. IN