Is key/cert rotation possible?

Hi Stéphane et team,

I’m currently using Gatling 3.5.1 as clients sending REST requests to server application that requires mTLS for every connection/request. Using provided perUserKeyManagerFactory function, I manage to set up KeyStore for mTLS with following code snippet -

def simKeyManager(id: Long): javax.net.ssl.KeyManagerFactory = {
val simKeyStore = new dataKeyStore() // java.security.KeyStore.getInstance(“pkcs12”)
simKeyStore.load(confKeyStores) // keyStore.load(new java.io.FileInputStream(keyFile), keySecret.toCharArray())
simKeyStore.manager // javax.net.ssl.KeyManagerFactory.init(keyStore, keySecret.toCharArray())
}

http
.baseUrls(confBaseUrls: *)
.headers(confHeaders)
.perUserKeyManagerFactory(simKeyManager(
))

Periodically, the server application requires Gatling clients to rotate their keys/certificates. For that, Gatling clients need to perform these operations:

  1. Delete existing key/cert from the existing KeyStore
  2. Create and add new key/cert into the existing KeyStore
  3. Reload the existing KeyStore

My understanding is KeyStore is loaded once at the protocol level. Is it possible that it can be reloaded in the scenario at later time?

Thank you for guidance/suggestion.

No, it’s not possible out of the box. That’s something you’ll have to implement yourself. Dealing with open connections during the rotation might prove tricky.

Hi Stéphane et team -

We managed to implement key/cert rotation functionality for our application

  • We create a new key pair in keystore on demand
  • We use the new key/cert for client authentication during SSL handshakes of subsequent requests

For the SSL contexts to find the new keys, we need to re-initialize them. Currently, SSL contexts are created and initialized once when scenarios are built, and stored in the Session:
https://github.com/gatling/gatling/blob/3.5/gatling-http/src/main/scala/io/gatling/http/cache/SslContextSupport.scala#L48-L56

Thus, we implement a patch to enable us to replace existing SSL contexts with new instances pointing to reloaded keystores/key managers.
https://github.com/vu-illumio/gatling-ssl-context-patch/commit/5627ac01cdf9ded7ff5e63481fcc93d878873d56

We need this functionality to re-initialize SSL contexts in Gatling for our application. If we could help with contribution, please let us know where to implement it properly.

Thank you for guidance.

Vu

Your solution doesn’t work because SslContextSupports is a stateless object that’s shared and used for all the protocols (remember, you can have one per scenario). You can’t make it stateful.

Generally speaking, we will never accept a change that’s only part of a solution.
If we were to support key rotation for ongoing virtual users, we would require a complete solution.

Regards,

Hi Stéphane et team -

Thank you for your explanation. The forementioned patch is indeed not a proper solution for general usage. It is a small hack that enables a functionality which we desperately need as described below.

Our application requires each virtual user to have its own keystore. Gatling provides the hook perUserKeyManagerFactory (https://gatling.io/docs/gatling/reference/current/http/protocol/#peruserkeymanagerfactory) to load the keystores once at the protocol engine which is instantiated at the beginning when scenarios are built. This functionality works well for us.

Additionally, our application requires usage of new keys/certs being added to the keystores over time (i.e. for key rotation). That requires Gatling to use the keystores more dynamically. We found that existing SSL contexts would need to be updated or replaced to use reloaded keystores on demand. We wish to avoid our current monkey patching approach and we are grateful if Gatling team would consider enabling this functionality in a near future release. If our contribution is needed, we ask to have your guidance to how best implement this functionality.

Regards,
Vu

Hi Vu,

Honestly, this feature is pretty complex to design, implement and test.
And yet, it’s non-strategic at this time (single free user use case), so we can’t hardly make it a priority.
I’m afraid that’s not something we can work on any time soon outside of a contract.

Please reach out privately if that’s something your organization might be interested in.

Regards,

Thank you, Stéphane. I’ll reach out to our management with your suggestion.