Using the SSL/TLS-based RMI Socket Factories in Java SE 6 with the JNDI/RMI Registry Service Provider

This is a followup of my previous blog entry Using the SSL/TLS-based RMI Socket Factories in J2SE 5.0.

In this new entry I will update the example to show you how SSL/TLS-based connections to the RMI registry are now supported in Mustang (Java SE 6) when using the JNDI/RMI Registry Service Provider.


Let's have a look first at the example using the JNDI/RMI Registry Service Provider but without any SSL/TLS protection at all.

  • Hello:
    public interface Hello extends Remote {
        public String sayHello() throws RemoteException;
    }
    
  • HelloImpl:
    public class HelloImpl extends UnicastRemoteObject implements Hello {
        public HelloImpl() throws RemoteException {
            super();
        }
        public String sayHello() {
            return "Hello World!";
        }
        public static void main(String args[]) throws Exception {
            // Bind this object instance to the name "HelloServer"
            HelloImpl obj = new HelloImpl();
            InitialContext ctx = new InitialContext();
            ctx.bind("rmi://localhost:3000/HelloServer", obj);
            System.out.println("HelloServer bound in registry");
        }
    }
    
  • HelloClient:
    public class HelloClient {
        public static void main(String args[]) throws Exception {
            // Lookup the remote reference bound to the name "HelloServer"
            InitialContext ctx = new InitialContext();
            Hello obj = (Hello) ctx.lookup("rmi://localhost:3000/HelloServer");
            String message = obj.sayHello();
            System.out.println(message);
        }
    }
    
  • RmiRegistry:
    public class RmiRegistry {
        public static void main(String[] args) throws Exception {
            // Start RMI registry on port 3000
            LocateRegistry.createRegistry(3000);
            System.out.println("RMI registry running on port 3000");
            // Sleep forever
            Thread.sleep(Long.MAX_VALUE);
        }
    }
    

In order to run the example open a shell window, go to the directory containing the compiled class files and call:

  • $ java RmiRegistry &
    RMI registry running on port 3000
  • $ java HelloImpl &
    HelloServer bound in registry
  • $ java HelloClient
    Hello World!

What would happen if the RMI registry had been started with the SSL/TLS-based RMI Socket Factories?

In J2SE 5.0, that would mean HelloImpl and HelloClient would have to access the RMI registry through the getRegistry method as shown in my previous blog entry.

In Mustang, the JNDI/RMI Registry Service Provider defines a new environment property com.sun.jndi.rmi.factory.socket that can be supplied in the InitialContext's Hashtable parameter. This environment property can be set to any socket factory of type RMIClientSocketFactory, i.e. the new environment property can be set to the SslRMIClientSocketFactory.


So let's finally protect the access to the RMI registry with SSL/TLS and modify HelloImpl and HelloClient in the example to let them access the RMI registry through SSL. As stated before, the SSL/TLS-based RMI Socket Factories used to create the RMI registry must require client authentication as this is the only way the RMI registry can refuse requests from clients sending untrusted certificates.

The following files need to be changed as follows:

  • HelloImpl:
    public class HelloImpl extends UnicastRemoteObject implements Hello {
        public HelloImpl() throws RemoteException {
            super();
        }
        public String sayHello() {
            return "Hello World!";
        }
        public static void main(String args[]) throws Exception {
            // Bind this object instance to the name "HelloServer"
            HelloImpl obj = new HelloImpl();
            Hashtable<String,Object> env = new Hashtable<String,Object>();
            env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
            InitialContext ctx = new InitialContext(env);
            ctx.bind("rmi://localhost:3000/HelloServer", obj);
            System.out.println("HelloServer bound in registry");
        }
    }
    
  • HelloClient:
    public class HelloClient {
        public static void main(String args[]) throws Exception {
            // Lookup the remote reference bound to the name "HelloServer"
            Hashtable<String,Object> env = new Hashtable<String,Object>();
            env.put("com.sun.jndi.rmi.factory.socket", new SslRMIClientSocketFactory());
            InitialContext ctx = new InitialContext(env);
            Hello obj = (Hello) ctx.lookup("rmi://localhost:3000/HelloServer");
            String message = obj.sayHello();
            System.out.println(message);
        }
    }
    
  • RmiRegistry:
    
    public class RmiRegistry {
        public static void main(String[] args) throws Exception {
            // Start RMI registry on port 3000
            LocateRegistry.createRegistry(3000,
                                          new SslRMIClientSocketFactory(),
                                          new SslRMIServerSocketFactory(null, null, true));
            System.out.println("RMI registry running on port 3000");
            // Sleep forever
            Thread.sleep(Long.MAX_VALUE);
        }
    }
    

In order to run the example open a shell window, go to the directory containing the compiled class files and call:

  • $ java -Djavax.net.ssl.keyStore=keystore -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=truststore -Djavax.net.ssl.trustStorePassword=trustword RmiRegistry &
    RMI registry running on port 3000
  • $ java -Djavax.net.ssl.keyStore=keystore -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=truststore -Djavax.net.ssl.trustStorePassword=trustword HelloImpl &
    HelloServer bound in registry
  • $ java -Djavax.net.ssl.keyStore=keystore -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=truststore -Djavax.net.ssl.trustStorePassword=trustword HelloClient
    Hello World!

Comments:

How would this example work if the client running through Web Start?

Anyway, is secure the client use the same keystore used by the server?

Regards,

Eldes

Posted by Eldes on April 22, 2008 at 04:27 PM CEST #

Hello,
your examples are pretty usefull and i understand the basics and implications of using rmi with ssl.
i have now a working c/s application using rmi with custom socketfactories. now i have to implement ssl.
can i use communication with and without ssl and let the socketfactories decide (createsocket()) can i use the same registry ?
thank you
michael

Posted by michael on January 14, 2009 at 06:57 AM CET #

Post a Comment:
  • HTML Syntax: NOT allowed
About

lmalvent

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today