inductiveautomation / ignition-module-tools

Tools that help in the creation and development of Modules for Inductive Automation's Ignition.
49 stars 14 forks source link

IGN-7871 PKCS#11 signing #43

Closed brianeray closed 8 months ago

brianeray commented 9 months ago

๐Ÿ“– Background

The signModule custom task in the gradle-module-plugin (a.k.a. io.ia.sdk.modl) supports PKCS#12 file-based Java keystores for signing modules. Certain software supply chain best practices recommend using PKCS#11-based hardware security modules (HSMs) for more secure keystore implementations. The private keys never leave the HSM, and the HSM itself signs the module digests.

โš™๏ธ Summary

Enhance the signModule task to allow for signing via HSM and other PKCS#11-compliant keystores. (Which need not be hardware tokens like YubiKeys, but may be cloud-based or other keystores implemented in software that are typically not local to the build machine.)

More specifically, add this capability via new property/option pkcs11CfgFile.

๐Ÿ“ Reviewer Notes

Use the Hide whitespace setting on the Files changed tab to eliminate a bunch of the delinting noise.

Because we call down to module-signer to do the actual signing, and because its filter is narrowed to keys of type SHA256withRSA, the key in the keystore must be that type. (This constraint predates the current enhancement.) At some point we'll likely enhance module-signer to support more key algorithms such as Elliptic Curve and whatever post-quantum algorithms ultimately pass muster with NIST and related entities.

On initial PR submission the version is 0.2.0-SNAPSHOT. After the PR is approved and any other validation--preferably some some testing by IA and partner developers--the PR will emerge from Draft status and the version will bump to 0.2.0. We may have to hand-crank publication to the Gradle Plugin repository as I'm not sure whether the release.yml workflow is working.

๐Ÿงช QA Notes

This was integration tested against a YubiKey 5 NFC with the wrinkle that the slot 9a authorization key was used, not the 9c signing key. There are notes in SignModuleTest as to why this workaround is necessary. (At some point we might be able to sign with the "correct" YK5 slot but it appears to require some tricky callback code.)

Fixes IGN-7871 (inductiveautomation/ignition-module-tools/issues/41)

brianeray commented 9 months ago

Holding off on merging until

  1. I figure out how to publish a snapshot build that internal and external developers can kick around a bit.
  2. Clean up that PR description.
  3. "Promote" the version from 0.2.0-SNAPSHOT to release 0.2.0.
  4. Publish that release version.
  5. Maybe get Perry to take a look at it since he wrote most of this + filed the internal ticket.
brianeray commented 8 months ago

QAed by both an integration partner using DigiCert KeyLocker and by IA QA with a YubiKey 5 and a genuine, non self-signed cert.

brianeray commented 8 months ago

See this IA forum post for instructions on using the new, 0.2.0 version of the plugin.

brianeray commented 8 months ago

Oddly enough we had a GitHub workflow that is still publishing to the Gradle Plugin Portal. 0.2.0 is up there now.