Error consuming web service due to lack of certificate in java (XML SOAP based)

user1084509 picture user1084509 · Jan 31, 2012 · Viewed 27.3k times · Source

I need to consume a web service which was built under Https in java. The Web Service Client was generated using Eclipse and to call it I use the following code:

ServicioTimbradoPruebasLocator ServicioTimbradoLocator = new ServicioTimbradoPruebasLocator();
                            ServicioTimbradoPruebasSoap ServicioTimbrado = ServicioTimbradoLocator.getServicioTimbradoPruebasSoap();
                            javax.xml.rpc.Stub s =((javax.xml.rpc.Stub)ServicioTimbrado);
                            s._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, "XXXXXXXX");
                            s._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, "psswd");          
                            String resultado = ServicioTimbrado.generaTimbre(xml.getBytes());
                            System.out.println("resultado: " +resultado);

On this line String resultado = ServicioTimbrado.generaTimbre(xml.getBytes()); I get the following error:

AxisFault
     [java]  faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
     [java]  faultSubcode: 
     [java]  faultString: 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
     [java]  faultActor: 
     [java]  faultNode: 
     [java]  faultDetail: 
     [java]     {http://xml.apache.org/axis/}stackTrace: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
     [java]     at sun.security.ssl.Alerts.getSSLException(Unknown Source)
     [java]     at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
     [java]     at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
     [java]     at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
     [java]     at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
     [java]     at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
     [java]     at sun.security.ssl.Handshaker.processLoop(Unknown Source)
     [java]     at sun.security.ssl.Handshaker.process_record(Unknown Source)
     [java]     at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
     [java]     at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
     [java]     at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
     [java]     at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
     [java]     at org.apache.axis.components.net.JSSESocketFactory.create(JSSESocketFactory.java:186)
     [java]     at org.apache.axis.transport.http.HTTPSender.getSocket(HTTPSender.java:191)
     [java]     at org.apache.axis.transport.http.HTTPSender.writeToSocket(HTTPSender.java:404)
     [java]     at org.apache.axis.transport.http.HTTPSender.invoke(HTTPSender.java:138)
     [java]     at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
     [java]     at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
     [java]     at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
     [java]     at org.apache.axis.client.AxisClient.invoke(AxisClient.java:165)
     [java]     at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
     [java]     at org.apache.axis.client.Call.invoke(Call.java:2767)
     [java]     at org.apache.axis.client.Call.invoke(Call.java:2443)
     [java]     at org.apache.axis.client.Call.invoke(Call.java:2366)
     [java]     at org.apache.axis.client.Call.invoke(Call.java:1812)
     [java]     at mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoapStub.generaTimbre(ServicioTimbradoPruebasSoapStub.java:107)
     [java]     at natura.facturacion.general.GuardarFacturaElectronicav2.doPost(GuardarFacturaElectronicav2.java:136) ...

I want to know if there is a way to send the certificate among with the webservice call. More information about the wsdl contract and the java generated files could be found here

Answer

Toby Jackson picture Toby Jackson · Jan 31, 2012

Depending on the version of Java you are using, one of the "recent" updates to the 1.6 JRE/JDK include a significant change in the global CACerts (the Trusted authority that signs SSL Certificats, for instance Verisign) to include some of the new certificate types that are around.

I recommend upgrading to the latest versions of Java to see if that works, if not, Option 2 is...

Using SSLPoke.java you can find out which certificates are missing, and the InstallCert.java to install them as follows;

  1. java InstallCert webserver.domain.com:443
  2. Copy the generated “jssecacerts” file to your “$JAVA_HOME\jre\lib\security” folder.

If this still causes issues, can you include the output from sslpoke, example usage;

# java SSLPoke webserver.domain.com 443
Successfully connected

If ALL that doesnt work, and you can get the certificate file (crt) you can manually import the file using the keytool command (cacerts is a file that will be created in your local working directory; ensure you move it into the java security folder in your JRE/JDK);

keytool -import -trustcacerts -alias AddTrustExternalCARoot -file cetificate.crt -keystore cacerts