1

I'm trying to send some audio binary data to an https rest service using a Worklight adapter, and since sending binary data is not supported (found here) I wrote my own Java class to do the rest call using wink.

Java code works for sure (it's a simple wink client with user/password authentication over https, tested and working in a standalone Java project), and in Worklight I didn't had to import the wink libraries since they are already available in the server runtime.

When I use the same Java code in Worklight, I got this exception:

[ERROR   ] FWLSE0099E: An error occurred while invoking procedure  [project CitizerCare]WatsonSpeechToText/recognizeSpeechFWLSE0100E:  parameters: [project CitizerCare]
java.lang.RuntimeException: 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
FWLSE0101E: Caused by:  [project CitizerCare]java.lang.RuntimeException: 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 targetorg.apache.wink.client.ClientRuntimeException: java.lang.RuntimeException: 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

And going down to the chain of "caused by", I got:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

I searched online and this seems to be related to the SSL certificate validation (problem and solution here, which basically explains how to create a keystore with the untrusted certificates). I imported my keystore (with the untrusted certificates) in Worklight as explained here, but still the exception is thrown.

Given that the keystore is the solution to my problem (not sure about that either), is it loaded also in the JVM where the Java adapter code runs? I don't really understand this behaviour, considering also that using plain HTTP Adapter I'm able to query the other https rest services without any issue! Even if discouraged, there is a way to disable the SSL certificate validation in Java?

Here the portion of code invoked:

public class WatsonSTT {

    private final static ClientConfig config = new ClientConfig();

    static {
        config.connectTimeout(60000*10).readTimeout(60000*10);
        BasicAuthSecurityHandler basicAuthSecHandler = new BasicAuthSecurityHandler(); 
        basicAuthSecHandler.setUserName(username); 
        basicAuthSecHandler.setPassword(password); 
        config.handlers(basicAuthSecHandler);
    }

    public static String query(String contentType, String base64data) throws JsonProcessingException, IOException {
        DoubleSession session = createSession();
        [...]
    }

    private static DoubleSession createSession() throws JsonProcessingException, IOException {

        RestClient client = new RestClient(config);

        Resource    resource = client.resource(restAddress + "/sessions");
                    resource.accept(MediaType.APPLICATION_JSON);
                    resource.header("Accept", "application/json");
                    resource.contentType("application/json");
                    resource.header("Content-Length", "0");

        ClientResponse response = resource.post(""); // Exception thrown

        [...]

    }

}

And the modification on worklight.properties:

ssl.keystore.path=conf/jssecacerts.keystore
ssl.keystore.type=jks
ssl.keystore.password=changeit
Community
  • 1
  • 1
pierpytom
  • 1,202
  • 1
  • 12
  • 25

2 Answers2

1

If you need to access any resource using SSL from custom native java code you need to implement also access to a keystore contains trusted certificates of backend server. The keystore that configured in worklight.properties used by worklight adapter implementation of WL.Server.invokeHttp(input) only, it is not loaded into the JVM. But you can import backend trust certificate into default OS or java keystore so the cert will be loaded by JVM and will be available for all java apps.

Pavel Leonov
  • 346
  • 1
  • 11
  • Since I don't know in which JVM the Java code of the adapter is running, I added this code in the class: static { String file = "/Users/pier/jssecacerts.keystore"; System.setProperty("javax.net.ssl.trustStore", file); System.setProperty("javax.net.ssl.keyStore", file); } Still no luck... – pierpytom Mar 04 '15 at 11:28
  • Try to add the cert to default OS truststore – Pavel Leonov Mar 19 '15 at 12:17
  • I was wondering if anyone had any luck getting this to work. I'm also calling a java method to base64 encode an image following the approach described here: https://www.ibm.com/developerworks/community/blogs/mobileblog/entry/ibm_worklight_adapter_accessing_an_image?lang=en where the image url is an https address and I'm also receiving an SSL exception. I've tried adding the cert to both the MFP keystore and the default JDK certstore without any success. Thanks! – JT-user2216025 Apr 22 '15 at 01:34
0

For the SSL problem try importing the cert into the default keystore found here: ${server.output.dir}/resources/security/key.jks versus the ssl keystore path found in the MobileFirst SSL Store - ssl.keystore.path=conf/mfp-default.keystore. That worked for me.