简体   繁体   中英

Setting up multiple SSL Socket Factories

I have a piece of Java code (actually a servlet) that needs to communicate securely with:

  1. another java process, via RMI, to make secure remote method calls and
  2. Google GCM Servers, to send notifications to mobile devices.

Here is the piece of code that bounds securely to the remote object:

    // let's set some system properties needed for RMI on SSL
    Properties sysProps = System.getProperties();
    sysProps.setProperty("javax.net.ssl.keyStore", ...);
    sysProps.setProperty("javax.net.ssl.keyStorePassword", ...);
    sysProps.setProperty("javax.net.ssl.trustStore", ...);
    sysProps.setProperty("javax.net.ssl.trustStorePassword", ...);

    try {
        String registryHost = ...;
        int registryPort = ...;

        Registry registry = LocateRegistry.getRegistry(registryHost, registryPort, new SslRMIClientSocketFactory());
        MyRemoteObject obj = (MyRemoteObject) registry.lookup(...);
    } catch (Exception e) {
        log.error("RMI Exception",e);
    } 

Then, to connect to Google GCM Servers, I have the only code supplied by Google and any tutorials I've read:

    config = new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
    config.setSecurityMode(SecurityMode.enabled);
    config.setReconnectionAllowed(true);
    config.setRosterLoadedAtLogin(false);
    config.setSendPresence(false);
    config.setSocketFactory(SSLSocketFactory.getDefault());

    // NOTE: Set to true to launch a window with information about packets
    // sent and received
    config.setDebuggerEnabled(true);

    // -Dsmack.debugEnabled=true
    XMPPConnection.DEBUG_ENABLED = false;

    connection = new XMPPConnection(config);
    connection.connect();

I can make one of these pieces of code work at a time, but I'm unable to establish both secure connections simultaneously. I can either use the default SSLSocketFactory OR set up a RMI SSL Socket factory, but not both. If I connect first to the RMI server I get the following error when I try to connect to Google GCM servers:

2014-09-08 16:14:05,172 ERROR [pool-4-thread-1] (GcmManager.java:109) - Problems connecting with Google XMPP servers
Connection failed. No response from server.: 
at org.jivesoftware.smack.PacketReader.startup(PacketReader.java:121)
at org.jivesoftware.smack.XMPPConnection.initConnection(XMPPConnection.java:636)
at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection.java:596)
at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:1010)
at com.tigratelecom.server.callback.web.notification.GcmManager.connect(GcmManager.java:171)
at com.tigratelecom.server.callback.web.notification.GcmManager.sendNotification(GcmManager.java:107)
at com.tigratelecom.server.callback.web.notification.NotificationSender.sendNotifications(NotificationSender.java:24)
at com.tigratelecom.server.callback.web.servlet.CallbackServlet$1.run(CallbackServlet.java:107)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:351)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)

whereas if I connect first to Google servers it all goes well until I try to connect to the RMI server, that fails with the following error:

java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: 
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:304)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:340)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at ...

Would you kindly point me in the right direction?

Thanks

I continued fiddling with this issue until I found something. I worked under the assumption that the code to connect to Google GCM servers (from the Smack library), since it used the default SSLSocketFactory, was using some certificate already present in the default java truststore, found in the jre/lib/security/cacerts in the java SDK installation. Since I had to create my own truststore and keystore to set up the RmiSSLSocketFactory, I assumed that the Smack library code was not able to locate whatever certificates it needed.

So what I decided to do was import all certificates available in cacerts into my own keystore. To do this, I ran:

keytool -importkeystore -srckeystore "c:\Program Files\Java\jdk1.7.0_25\jre\lib\security\cacerts" -destkeystore my_truststore  -srcstorepass changeit -deststorepass mypass

After that, all went well and both secure connections were established without issues.

I hope this helps someone in the future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM