Certificate based mutual authentication - setKeyAndChain?

I am implementing certificate-based mutual TLS authentication with WM integration server as the client, making HTTPS GET/POST calls to another (non-WM) server. This means that IS has to present a client certificate to the remote web server to authenticate. Moreover, the IS must dynamically choose the client certificate to present at runtime, based on various criteria.

From what I have read, I believe the way to do this is to preselect the client certificate with pub.security.keystore:setKeyAndChain and then call pub.client:http.

  • Is this correct?
  • If so:
    • what is the scope/impact of the setKeyAndChain call - e.g. does it only affect the current thread, and for how long (e.g. until service exit)? Does it affect the connection pool?
    • how do I **un**setKeyAndChain i.e. stop using the client certificate for subsequent HTTP calls?
    • Does setKeyAndChain mess with IS’s ability to authenticate the remote server using its default trust store?
  • Is there a better way?

Hi Michael,

did you check the IS Built-In-Services Reference as well as the IS Administrators Guide regarding certificate handling?

IS uses a default server certificate and truststore for his HTTPS ports.
If these are not applicable for certain ports you can configure the ports to use another certificate from your Keystore Aliases.

Regards,
Holger

Hi Michael,

This should be a one time setup normally for you to exchange your certs with the target hosting server to invoke their WS or making http call.

Why do you want to pass these values dynamically during run time using built in services? Any specific reason behind doing this.

Probably you can refer the Integration Server Built-in Services guide and explore options from available built-in services though.

Regards,
Firoz N

1 Like

Hi Michael,

you might want explore the WS Endpoitn Aliases feature, afaik these are also able to present the certificates based on the Keystore and Truststore Aliases.

Regards,
Holger

Hi Firoz,
Certificate exchange will be handled outside of this process during the deployment phase, prior to attempting to use mTLS. We need to dynamically choose the client certificate we present to the end server because the WM application will in some situations be acting as a proxy for other systems, and when it makes an HTTPS call to system X it may need to represent itself as client A, client B, or client C (each of which is identified by a different client certificate).

Hi Holger,

Yes, I have gone through the documentation have have not yet found any specific information. I found no details all about the duration and scope of the pub.security.keystore:setKeyAndChain. As this is a stateful action impacting the runtime behaviour, I want to know how long the state will exist and how far it reaches. “Associates a key and certificate chain with the subsequent set of invoked services” is not very specific (to me, anyway :slight_smile: ).

Hi Holger,
I looked at the Web Service Consumer Endpoints. They do have the right sorts of configuration, but I haven’t worked out how to make use them in plain HTTPS calls as opposed to WSDL/SOAP MSHs.

Michael -

My understanding of setKeyAndChain’s scope is it’s limited to the current Flow. It doesn’t affect other service threads or subsequent HTTP calls. There’s also clearKeyAndChain, if you want to explicitly revert to the default keystore before ending the Flow service.

That’s a good question. Based on the name of the service (i.e., “set key and [the key’s CA] chain”), I suspect IS default truststore operation is unaffected.

In other words, what you’re changing is the client key used for X.509 client authentication. Whether IS trusts the server certificate presented by the remote SSL server is still decided by the default IS truststore and/or relevant IS settings (such as ones to trust CAs by default, or ignore expired certificates)

2 Likes

Hi Michael,
Yes,using the pub.security.keystore:setKeyAndChain before the pub.client:http is the recommended approach if you want to set different certificate for each HTTP outbound call.

To answer your queries
what is the scope/impact of the setKeyAndChain call - e.g. does it only affect the current thread, and for how long (e.g. until service exit)? Does it affect the connection pool?

The service setKeyAndChain set the certificates in the current invoke state so it will affect current flow or thread invocation. And calling clearKeyAndChain clears it from the Invoke state so unless clearKeyAndChain is called certificates will remain in the invoke state and if there is any subsequent pub.client:http it will be used. No it doesn’t affect connection pool as connection pool is maintained based on endpoints. Say if you send 2 HTTP requests to www.google.com and www.amazon.com and connection pooling is enabled, then there will 2 separate connections pools, one for www.google.com and one for www.amazon.com.

  1. how do I unsetKeyAndChain i.e. stop using the client certificate for subsequent HTTP calls?

Use public service “clearKeyAndChain” to clear the certificates from the invoke state and subsequent HTTP calls in the same flow will not use it.

  1. Does setKeyAndChain mess with IS’s ability to authenticate the remote server using its default trust store?

No because “setKeyAndChain” sets the private keys/certificates only that client want to send to external server. Default truststore (i.e. one that is configured at Security > Certificates ) is used to validate any remote server.

1 Like

Jaideep, in this scenario, if I use client certificate A (via setKeyAndChain) to call [www.amazon,.com], fail to call clearKeyAndChain, then return the connection to the pool, when another thread picks up this connection from the pool, will it still be associated with client certificate A?

Yes, if the next thread is also calling www.amazon.com and pooled socket is still valid.

1 Like

@Michael_Lemaire, @Jaideep - sorry to intrude: what sort of connection pooling are you discussing with HTTP connections?

I thought HTTP connections are not pooled in IS. That’s because HTTP has traditionally been “stateless” (each work request is fulfilled by setting up a fresh HTTP connection).

Is there some pooling mechanism that uses HTTP ‘Keep-Alive’ headers or somesuch?

Hi Sonam,

From the IS Built-In Services Reference (10.3) page 116:
For the HTTP request, the pub.client:http service uses a client connection from a client connection pool.

I assume (as you say) that IS is using “Keep-alive” to make the connections persistent, so they can be used for multiple requests to a server rather than being discarded after making a single request. This saves a lot of overhead in terms of opening sockets, negotiating TLS, passing certificates, and setting up encryption, especially when you have a small number of target servers to which the IS sends thousands of requests per hour.

Thanks @Michael_Lemaire – you’re right! And here, I’ve been happily ignoring HTTP connection pooling for years. It’s testament to webMethods being (mostly) idiot proof :slight_smile:

@Jaideep is right - calling clearKeyAndChain is good practise, and so is calling pub.io:close if pub.client:http set loadAs=stream.

Though I suspect that even if you don’t call close, the setting below ‘reaps’ idle HTTP connections, so HTTP sessions don’t ‘leak’.

watt.net.clientKeepaliveTimeout
Controls how long (in seconds) a client keep alive connection can remain idle before

Integration Server closes it. The default is 180 seconds (3 minutes).

2 Likes