Java Dynamic Management Kit 5.1 Tutorial

11.4.3 TLS Socket Factory

Your JMXMP connections can also be secured using an implementation of Transport Layer Security (TLS) sockets, as shown in the following example. This example is taken from the sub-directories of examplesDir/current/Security/jmxmp/tls_factory. The example shows how to provide a custom configured TLS factory for use by the client and the server.


Example 11–16 Securing a JMXMP Connector Server Using TLS Socket Factories

public class Server { 
 
    public static void main(String[] args) { 
      try { 
           MBeanServer mbs = MBeanServerFactory.createMBeanServer(); 
           HashMap env = new HashMap(); 
           String keystore = "config" + File.separator + "keystore"; 
           char keystorepass[] = "password".toCharArray(); 
           char keypassword[] = "password".toCharArray(); 
           KeyStore ks = KeyStore.getInstance("JKS"); 
           ks.load(new FileInputStream(keystore), keystorepass); 
           KeyManagerFactory kmf = 
              KeyManagerFactory.getInstance("SunX509"); 
           kmf.init(ks, keypassword); 
           SSLContext ctx = SSLContext.getInstance("TLSv1"); 
           ctx.init(kmf.getKeyManagers(), null, null); 
           SSLSocketFactory ssf = ctx.getSocketFactory(); 
           env.put("jmx.remote.profiles", "TLS"); 
           env.put("jmx.remote.tls.socket.factory", ssf); 
           env.put("jmx.remote.tls.enabled.protocols", "TLSv1"); 
           env.put("jmx.remote.tls.enabled.cipher.suites", 
                 "SSL_RSA_WITH_NULL_MD5"); 
 
           JMXServiceURL url = new JMXServiceURL("jmxmp", null, 5555); 
           JMXConnectorServer cs = 
              JMXConnectorServerFactory.newJMXConnectorServer(url, 
                                                              env, 
                                                              mbs); 
           cs.start(); 
 
         } catch (Exception e) { 
           e.printStackTrace(); 
         } 
      } 
  } 

Example 11–16 shows the creation of an MBean server mbs, an environment map env, and a key store object ks. The key store object ks is initialized by loading in the input stream keystore and the key store password, keystorepass, that grants access to the key store.

An instance of the SSL class KeyManagerFactory, named kmf, that implements the SunX509 key management algorithm, is then initialized. The kmf instance is passed the key information contained in the key store ks and the key password keypassword that grants access to the keys in the key store.

The SSL context, ctx, is set to use the protocol version TLSv1, and is initialized with kmf as its key manager. Finally, an instance of SSLSocketFactory, named ssf, is created by calling the getSocketFactory() method of the SSL context ctx.

The environment map env is populated with the TLS profiles, the SSL socket factory ssf, the TLSv1 protocol version, and the SSL_RSA_WITH_NULL_MD5 cipher suite.

Finally, with an instance of JMXConnectorServer, named cs, is created. The connector server cs is started by a call to the start() method of JMXConnectorServer.


Example 11–17 Securing a JMXMP Connector Client Using TLS Socket Factories

public class Client { 
 
   public static void main(String[] args) { 
     try { 
          HashMap env = new HashMap(); 
          String truststore = "config" + File.separator + "truststore"; 
          char truststorepass[] = "trustword".toCharArray(); 
          KeyStore ks = KeyStore.getInstance("JKS"); 
          ks.load(new FileInputStream(truststore), truststorepass); 
          TrustManagerFactory tmf =  
             TrustManagerFactory.getInstance("SunX509"); 
          tmf.init(ks); 
          SSLContext ctx = SSLContext.getInstance("TLSv1"); 
          ctx.init(null, tmf.getTrustManagers(), null); 
          SSLSocketFactory ssf = ctx.getSocketFactory(); 
          env.put("jmx.remote.profiles", "TLS"); 
          env.put("jmx.remote.tls.socket.factory", ssf); 
          env.put("jmx.remote.tls.enabled.protocols", "TLSv1"); 
          env.put("jmx.remote.tls.enabled.cipher.suites", 
             "SSL_RSA_WITH_NULL_MD5"); 
 
          JMXServiceURL url = new JMXServiceURL("jmxmp", null, 5555); 
          JMXConnector jmxc = JMXConnectorFactory.connect(url, env); 
          MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); 
          String domains[] = mbsc.getDomains(); 
          for (int i = 0; i < domains.length; i++) { 
          System.out.println("Domain[" + i + "] = " + domains[i]); 
          } 
 
          ObjectName mbeanName = 
              new ObjectName("MBeans:type=SimpleStandard"); 
          mbsc.createMBean("SimpleStandard", mbeanName, null, null); 
          // Perform MBean operations 
          // 
          [...] 
          mbsc.removeNotificationListener(mbeanName, listener); 
          mbsc.unregisterMBean(mbeanName); 
          jmxc.close(); 
        } catch (Exception e) { 
          e.printStackTrace(); 
        } 
     } 
} 

As for the Server, Example 11–17 shows the creation of an environment map env, and a key store object ks for the JMXMP connector Client. The key store object ks is initialized by loading in the input stream truststore and the password, truststorepass, that grants access to the trust store.

An instance of the SSL class TrustManagerFactory, named tmf, that implements the SunX509 key management algorithm, is then initialized. The tmf instance is passed the key information contained in the key store ks.

The SSL context, ctx, is set to use the protocol version TLSv1, and is initialized with tmf as its trust manager. Finally, an instance of SSLSocketFactory, named ssf, is created by calling the getSocketFactory() method of the SSL context ctx.

The environment map env is populated with the the SSL socket factory ssf, the TLSv1 protocol version, and the SSL_RSA_WITH_NULL_MD5 cipher suite.

An instance of JMXConnector, named jmxc is then created, and an MBean server connection, mbsc, is made by calling the getMBeanServerConnection method of the JMX Remote API connector jmxc.

In code that is not shown here, when the connection to the MBean server has been established, the Client creates an MBean called SimpleStandard and performs various operations on it. Once these MBean operations have completed, the Client unregisters the MBean, and closes down the connection jmxc.

To Run the Secure JMXMP Connector Example with TLS Socket Factories

Run this example from within the examplesDir/current/Security/jmxmp/tls_factory directory.

  1. Compile the Java classes.


    $ javac -classpath classpath \
          mbeans/SimpleStandard.java \
          mbeans/SimpleStandardMBean.java \
          server/Server.java \
          client/Client.java \
          client/ClientListener.java 
    
  2. Start the Server.


    $ java -classpath server:mbeans:classpath Server & 
    

    You will see confirmation of the creation of the MBean server, the initialization of the environment map and the launching of the JMXMP connector and its registration in the MBean server.

  3. Start the Client.


    $ java -classpath client:mbeans:classpath Client 
    

    You will see confirmation of the creation of the JMXMP connector client, the initialization of the environment map, the connection to the MBean server and the performance of the various MBean operations followed by the closure of the connection.