4
votes

I have created a web service in Java which posts data to another web service. This requires SSL certificates for authentication. This web service is running fine on Tomcat, but when I deploy the same code on GlassFish 3.0.1 server, I am getting javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown ca exception. I have imported the certificate to glassfish trustStore using keytool. The required certificates are provided by client.

My code:

System.setProperty("javax.net.ssl.keyStoreType" , "pkcs12");
System.setProperty("javax.net.ssl.keyStore", applicationRootDirPath + "clientCert.p12");
System.setProperty("javax.net.ssl.keyStorePassword", "password");

System.setProperty("javax.net.ssl.trustStoreType", "jks");
System.setProperty("javax.net.ssl.trustStore", "path of glass fish truststore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

try {
    url = new URL(serverUrl);
    urlConn =  url.openConnection();
    urlConn.setDoOutput(true);
    urlConn.setRequestMethod("POST");
    urlConn.setAllowUserInteraction(false);
    urlConn.setUseCaches(false);
    urlConn.setRequestProperty("Content-type", "text/xml; charset=utf-8");
    urlConn.setRequestProperty("Content-Length", new Integer(xml.length()).toString());

    try {
        writer = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8");
        writer.write(xmlData);
    } finally {
        if (writer != null) {
            writer.close();
        }
    }
    trace += "\n urlConn.getInputStream()";
    in = urlConn.getInputStream();      
}
2
Check the domain.xml file in glassfish for the ssl params.Zaki
Thanks Zaki for your reply. I have installed certificates in the path provided in domain.xml. Even I tried by changing glass fish keystore and truststore paths(tried by providing absolute paths) from domain.xml.Please advice me what else I should look for.mahesh
Is the server's certificate a self-signed one? Look into the server.log file in $GF_HOME/glassfish/domains/your_domain/logs for the complete exception details, without which it is pretty hard to narrow it down.Zaki
Zaki, I did not see any log in logs folder. I am new to glass fish. How do I enable glass fish logs??mahesh
After digging a lot,I found reason behind the unknown_ca error. Actually,glass fish was presenting some other certificate as trusted certificate.So I have removed all the certificates from glass fish keystore and installed my certificate.Now after deploying application,I am getting "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" exception. I have installed certificate in glass fish trust store and keystore.pls help.mahesh

2 Answers

0
votes

What is the development environment that you are using? If you are using NetBeans, you have to set these in VMargs in /etc/netbeans.conf (this is needed for proper web service tool functionality, so that you can generate clients for example):

<NETBEANS_HOME>/bin/netbeans.exe
-J-Djavax.net.ssl.trustStore=<AS_HOME>/domains/domain1/config/cacerts.jks 
-J-Djavax.net.ssl.keyStore=<AS_HOME>/domains/domain1/config/keystore.jks 
-J-Djavax.net.ssl.trustStorePassword=changeit 
-J-Djavax.net.ssl.keyStorePassword=changeit

Also, make sure that you have set up the truststore in GlassFish correctly; add these lines exactly like this to the JVM options:

-Djavax.net.ssl.trustStore=${truststore.location}
-Djavax.net.ssl.trustStorePassword=${ssl.password}

Also, if it is not a valid certificate (e.g hostnames do not match, which is a common reason of javax.net.ssl.SSLHandshakeException), you can do a workaround in the client web service for development/testing purposes:

static {
     //WORKAROUND. TO BE REMOVED.
     javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
     new javax.net.ssl.HostnameVerifier(){
         public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
                if (hostname.equals("mytargethostname")) { //Change to actual value
                     return true;
                }
                return false;
         }
     });
}

At the moment I don't see the source of your problem, but these are some points I think you should troubleshoot at.

0
votes

You need to specify the following JVM option, as well:

-Dcom.sun.enterprise.security.httpsOutboundKeyAlias=[alias of the client certificate in your keystore]