Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 313
user1084509 Avatar asked Jan 31 '12 19:01

user1084509


2 Answers

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

like image 136
Toby Jackson Avatar answered Nov 07 '22 18:11

Toby Jackson


You can refer to this thread: How to handle invalid SSL certificates with Apache HttpClient?

Of course here you have a WSDL SOAP Web Service, there you have an Apache HTTP Client, but the error is the same and you can handle it in the same way (or ways).

You can:

1 - Force your program to accept ANY SSL certificate

2 - Download and install in your JVM the SSL certificate that you're missing

The 1st one is easier (in the most of the case), but you should use it ONLY before the release or you'll be easily exposed to a "Man in the middle attack". The 2nd (usually) a better choice.

Here there is a synthetic but well explained documantation to those 2 points described before with code samples: http://ws.apache.org/xmlrpc/ssl.html

like image 32
thermz Avatar answered Nov 07 '22 18:11

thermz