RMI + SSL need help

Hi,

i want create a simple RMI program with SSL sockets but when i run the client i've this type of error:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)

at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322)

at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)

at it.enginSoft.rmitextclient.Client.main(Client.java:65)

Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)

at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1586)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:865)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1029)

at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:621)

at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)

at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)

at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)

at java.io.DataOutputStream.flush(DataOutputStream.java:106)

at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:211)

... 4 more

Here is my Client Code:

publicstaticvoid main(String[] args){

String ip =null;

String port =null;

try{

ip = args[0];

port = args[1];

}catch(Exception e){

System.err.println("USAGE: Client server_address port");

e.printStackTrace();

System.exit(1);

}

//Create and install a security manager

if (System.getSecurityManager() ==null){

System.setSecurityManager(new SecurityManager());

}

System.setProperty("javax.net.ssl.truststore","C:\\Projects\\RMITextServer\\RMITextServer\\src\\server.keystore");

System.setProperty("javax.net.ssl.keyStorePassword","passwd");

try

{

RMIClientSocketFactory csf =new SslRMIClientSocketFactory();

Registry registry = LocateRegistry.getRegistry(ip,Integer.parseInt(port),csf);

IText remoteObject = (IText)registry.lookup ("RMIText");

String result = remoteObject.text("Hello World!!");

System.out.println(result);

}

catch(Exception e){

System.err.println("Client exception: " + e.getMessage() +" see below for details");

e.printStackTrace( );

}

}

And my server code is this:

publicstaticvoid main(String[] args){

// TODO code application logic here

//creo il security manager

if (System.getSecurityManager() ==null){

System.setSecurityManager(new SecurityManager());

}

System.setProperty("javax.net.ssl.keystore","C:\\Projects\\RMITextClient\\RMITextClient\\src\\client.keystore");

System.setProperty("javax.net.ssl.keyStorePassword","passwd");

try

{

RMIClientSocketFactory csf =new SslRMIClientSocketFactory();

RMIServerSocketFactory ssf =new SslRMIServerSocketFactory();

Registry registry = LocateRegistry.createRegistry(4444,csf,ssf);

IText text =new Server();

registry.bind("RMIText",text);

System.out.println("RMIText bound in registry");

}

catch (Exception e){

System.err.println("Server exception: " + e.getMessage() +" see below for details");

e.printStackTrace( );

System.exit(1);

}

}

Can anyone help me? I've read your post about RMI with SSL but without success..

Thanks

Luka

[5623 byte] By [lukaTNa] at [2007-11-27 9:53:37]
# 1

Hi,

I had to add these args to my command-line to become functional:

-Djava.security.policy=server.policy -Djavax.net.debug=ssl:handshake

using the stnd server.policy file that gives me correct perms. Mine is here:

grant {

permission java.security.AllPermission;

permission java.security.AdminPermission;

permission java.io.FilePermission "<>", "read, write";

permission javax.sound.sampled.AudioPermission "record";

permission java.util.PropertyPermission "user.dir", "read";

permission javax.speech.SpeechPermission "javax.speech";

permission java.lang.RuntimePermission "loadLibrary.jsapi";

permission java.lang.RuntimePermission "modifyThread";

permission java.net.SocketPermission "*:1024-65535", "connect, accept, resolve";

permission java.io.FilePermission "<<ALL FILES>>", "read, write, delete, execute";

permission java.util.PropertyPermission "user.dir", "read, write";

};

Note the java.net.SocketPermission above.

There is an entire set of debugging outputs available from the second parm above. Try running your code with it.

There is also a good section on SSL in the RMI topic at Sun. You don't say how you are being or recognizing certifications, or whether you are self-certified, which creates another set of problems.

Have you looked at your certs in their respective keystore and truststore?

This is a very deep topic, but one you must understand to correctly provide the security you need, while providing your users the access they need. This was a major block of time to get this working, but it was worth it!

EJavaM

EJavaM07a at 2007-7-13 0:22:55 > top of Java-index,Core,Core APIs...
# 2

when i run i've got the same error:

maybe the truststore is wrong..

so..

i've created truststore and keystore with this command lines:

for generate the keysore:

keytool -keygen -alias duke -keyalg "RSA" -keystore keystore -storepass 123456 -validity 360

for generate the certificate:

keytool -export -alias duke -keystore keystore -rfc -file duke.cer

for generate the truststore:

keytool -import -alias duke -file duke.cer -keystore truststore

I apologize me but i'm not so expert in RMI and Java..

have anyone any hint about the generation of a correct trust/key store?

thanks a lot

Luka

lukaTNa at 2007-7-13 0:22:55 > top of Java-index,Core,Core APIs...
# 3

OK!!! PROBLEM SOLVED!! =D

The problem was the set of the keystore parameters. Yesterday i set key and trust store in the code by "System.setProperty(...)" but it doesn't work.

Today by setting key and trust store from command line everythink work fine!!

as policy i've used

grant {

permission java.security.AllPermission;

};

and it work!! :-)

Thanks a lot for your answer and if someone is interested in RMI + SSL example write me an email.. =D

ciao

Luka

lukaTNa at 2007-7-13 0:22:55 > top of Java-index,Core,Core APIs...
# 4

Why is the server's keystore called 'client.keystore'?

Why is the client's truststore called 'server.keystore'?

Why are you providing a keyStorePassword to the client when you aren't providing a keyStore?

I think you need to brush up on the functions of all these things. See http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html

ejpa at 2007-7-13 0:22:55 > top of Java-index,Core,Core APIs...
# 5

sorry..i've swap the keys.. :-P

so..i've created the them in this way..

1. Creation a self-signed server and a self-signed client key each in its own keystore

keytool -genkey -v -keyalg RSA -keystore server.keystore -dname "CN=Server, OU=Bar, O=Foo, L=Some, ST=Where, C=UN"

keytool -genkey -v -keyalg RSA -keystore client.keystore -dname "CN=Client, OU=Bar, O=Foo, L=Some, ST=Where, C=UN"

2. Exportation of the server's and the client's public keys from their respective keystores

keytool -export -rfc -keystore server.keystore -alias mykey -file server.public-key

keytool -export -rfc -keystore client.keystore -alias mykey -file client.public-key

3. Importation of the client's public key to the server's keystore, and vice-versa:

keytool -import -alias client -keystore server.keystore -file client.public-key

keytool -import -alias server -keystore client.keystore -file server.public-key

I've take these from an example in the web. Should be correct..

What do you think about?

Thanks

Luka

lukaTNa at 2007-7-13 0:22:55 > top of Java-index,Core,Core APIs...
# 6
> 3. Importation of the client's public key to the server's keystore, and vice-versa:No. You must import the client's public key to the server's truststore, and vice versa.> I've take these from an example in the web. Should be correct..It's not.
ejpa at 2007-7-13 0:22:56 > top of Java-index,Core,Core APIs...