Hi,
This is for webMethods Integration server 9.10, but a test today on version 10.5 show same behavior.
I created a Consumer Web Service Descriptor from a WSDL file, as described in 9-10_Web_Services_Developers_Guide.pdf file (version 10.5 document is the same). I called it “testabc”. This generates properly a folder called “testabc_” with 3 folders called “connectors”, “docTypes” and “responseServices” which correspond to the service port defined in my WSDL as well as the data elements I defined in my WSDL.
The input/output of the newly created Web Service Connector are as explained in the Web Services Developers Guide under a section called “Signature for a Web Service Connector”.
If the provider of the web service does not ask for authentication of any sort, I am able to invoke this Web Service Connector by setting the request input (in my case: tns:request
), setting up _url
to the http or https address of the server which will process the transaction.
My issue is that I need to use a client certificate to authenticate at the transport level to a remote web service server, using https, and this is not working. The consumer Web Service Connector is not sending the client certificate to the remote server.
I added the remote server root CA and intermediate CA certificates in my <IIS install folderr>/common/conf/platform_truststore.jks
by using a tool called “KeyStore Explorer”, then I reloaded the “DEFAULT_IS_TRUSTSTORE” using Web Methods admin console -> Security -> Keystore
, and for DEFAULT_IS_TRUSTSTORE
I clicked on the Reload icon. I’m not sure this was absolutely required to tell Integration Server to trust the certificates issued by this CA, but just in case I did that.
Then, to keep things simple, instead of trying to add a new private key under Security -> Keystore -> Keystore List
, I decided to attempt to use the pre-existing default Key Alias key called ssos in Keystore alias DEFAULT_IS_KEYSTORE, as being the client certificate.
So I wrote a little wrapper around the web service connector to set the following inputs:
auth/transport/serverCerts/keyStoreAlias : DEFAULT_IS_KEYSTORE
auth/transport/serverCerts/keyAlias : ssos
_url: https:/my.remote.server.com/the/soap/service
(this isn’t the real url)
useJSSE: Yes
Note: using useJSSE=Yes
forces webMethods to use the Java security encryption routines instead of webMethods builtin routines, this is required to support TLSv1.1 and TLSv1.2
When I call the service, I get a fault with fault/reasons/reasons[0]/*body
set to:
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
I used tcpdump to capture all the packages into a file, and then I used Wireshark to analyze that result, and what I see is that webMethods does not attempt to use any client certificate as can see in the trace below, packet 10 the “Certificate, Client Key Exchange”, in the details of the packet, the “Certificates Length” is set to 0 (no certificate was sent by web methods)
Please note that if I use something else than webMethods to call the same web service, the client cert is send and Certificates Length is then greater than zero.
I then looked at the Web Service Connector, and I see that it uses pub.client:soapClient
. What I saw is quite puzzling, the auth
parameter of soapClient is not defined the same way as the one from the web service connector. soapClient is using auth/transport/serverCerts/privateKey
and auth/transport/serverCerts/certChain
instead of auth/transport/serverCerts/keyStoreAlias
and auth/transport/serverCerts/keyAlias
:
The parameters of soapClient are defined in the webMethods Integration Server Built-In Services Reference and it does mention it should be serverCerts/privateKey
and serverCerts/certChain
.
How could that be possible to not be the same?
Thinking that maybe I really need to use what soapClient is telling to use, I edited the connector by calling pub.security.keystore:getKeyAndChain
with input:
keyStoreAlias: DEFAULT_IS_KEYSTORE
keyAlias: ssos
this produces privateKey and certChain:
Which I then used as input to calling pub.client:soapClient
:
When I run this in debug mode, the call to pub.security.keystore:getKeyAndChain
returns:
privateKey: sun.security.rsa.RSAPrivateCrtKeyImpl@22eb04
certChain/certChain[0]: [B@c180430
and the call to soapClient returns:
response/fault/reasons/reasons[0]/*body
:
com.wm.util.ServerException: WS_CLIENT_INVALID_PRIVATE_KEY
(and no call is made out to the remote server).
I was doing all my tests on WM9.10, but I recently got access to a WM10.5, so I imported my package in WM10.5 and the results are the same.
As anyone used transport level authentication with a client certificate successfully from a consumer web service?
Does anyone has a pointer as to what I am doing wrong?