XML-RPC over SSL


Let’s assume that we’ve got an XML-RPC server running @ https://localhost:8443/calculator/xmlrpc
It can either add/subtract numbers.

Here’s the server-side logic for it:

Calculator.java

public class Calculator {

public int add(int i1, int i2) {
return i1 + i2;
}

public int subtract(int i1, int i2) {
return i1 - i2;
}
}

Let’s write a simple XML-RPC client program that’ll connect to the server and get two numbers added.

import java.net.URL;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

public class TestRPCClient {

public static void main(String[] args) throws Exception {

XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("https://localhost:8443/calculator/xmlrpc"));
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
Object[] params = new Object[] { new Integer(30), new Integer(8) };
Integer result = (Integer) client.execute("Calculator.add", params);
System.out.println("The returned values are: " + result);

}

}

Okay, all set. Now, if we run this client program, we’ll get a lengthy exception:

Failed to read server’s response: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.

Now, the quickest fix/solution is to tell the client that you want to accept any certificate, regardless of issuer and host. This’s how you’ve to write the code:

import java.net.URL;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;

public class TestRPCClient {

public static void main(String[] args) throws Exception {

XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("https://localhost:8443/xml5/xmlrpc"));
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);

Object[] params = new Object[] { new Integer(32), new Integer(9) };
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}

public void checkClientTrusted(X509Certificate[] certs,
String authType) {
// Trust always
}

public void checkServerTrusted(X509Certificate[] certs,
String authType) {
// Trust always
}
} };

// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
// Create empty HostnameVerifier
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
};

sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hv);

Integer result = (Integer) client.execute("Calculator.add", params);
System.out.println("The returned values are: " + result);

}

}

That’ll give you the result!

About these ads

About this entry