Skip to content

Update auto-provisioning JMeter plans for the X.509 challenge exchange #3542

Open

Description

@richturner

Problem

MQTT X.509 auto provisioning now requires the device to prove it holds the private key for its
certificate (GHSA-7jp3-2229-xgqj). Certificate-only x509 requests are rejected with
UNAUTHORIZED, so both load test plans fail at the provisioning step:

  • test/load1/deployment3/auto-provisioning.jmx
  • test/load1/deployment3/auto-provisioning-settle-test.jmx

The protocol is documented in the
auto provisioning docs
(updated by openremote/documentation#204) and in the UserAssetProvisioningMQTTHandler javadoc,
and UserAndAssetProvisioningTest has a working client.

Required changes

Plans

For each device thread:

  1. Subscribe to provisioning/${id}/response (already first; only the connection that owns this
    topic may publish requests, and a connection may own only one response topic).
  2. Publish {"type":"x509-challenge-request","cert":"${cert}"} to provisioning/${id}/request.
  3. Wait for the x509-challenge response. In a JSR223 (Groovy) post-processor:
    • check the challenge starts with OpenRemote MQTT X509 provisioning v1\n followed by
      provisioning/${id}/request
    • sign the exact UTF-8 bytes of challenge using algorithm (SHA256withRSA for the
      generator's RSA key) and Base64 encode it
    • load and parse the private key once and cache it in props, not per thread or per sample
  4. Publish {"type":"x509","cert":"${cert}","signature":"${signature}"} to the same request topic.
  5. Wait for the success response and move the existing asset ID regex extractor onto it.

Device key and CSV

  • The private key used to generate the committed deployment3/devices.csv is not in the repo
    (device_generator.sh writes it to tmp/device.pem and deletes tmp/ on each run), so the
    committed certificates can no longer be used.
  • Change device_generator.sh to keep the device key somewhere durable (or accept an existing
    one), commit a test-only device key next to the plans (the load1 CA key is already committed
    under setup/src/load1), and regenerate devices.csv with it.
  • Make sure the key is shipped to the load generators alongside devices.csv in the Taurus
    *.yml configs.

Things to verify

  • That the XMeter SubSampler (async) + AsyncResponseSampler combination can wait for a
    second message on the same subscription; if not, use two sampling windows or a JSR223 sampler
    for the exchange.
  • That a run with a small THREAD_COUNT against a local manager provisions every device, then
    a full 10k run to compare provisioning throughput with the previous single-step exchange
    (there is now one extra round trip and a signature verification per device).

Done when

  • Both plans provision and run against a manager that includes the fix.
  • test/load1/README.md no longer describes the plans as broken.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions