Given new requirements for Code Signing (see this write up from Comodo) we are trying to perform our Code Signing using an Hardware Security Module (HSM) setup within Azure Key Vault. The consequence of this is that we (apparently) cannot get a .pfx file (with private key) as we have in the past.
We chose NOT to use the USB Key option as this seems to be unworkable with build pipelines, distributed work force, etc.
However all of this creates challenges using the IA supplied module-signer as it seems to require a .pfx file as input; at least this is how we have done it in the past.
I was able to sign the .modl file directly using a Maven package from Microsoft and instructions for this GitHub repos.
However looking at the code from IA it adds in the .p7b file and a custom signatures.properties file. While I can simply add the .p7b file myself with a custom method, the signatures.properties file is another story. In my testing I was partially successful doing this but I suspect (understandably) that the signature.properties file being improper (copied an old one) or missing (since I have no way to generate this) is an issue.
With all of that background and given these new requirements for using an HSM for Code Signing does anyone have any suggestions on how we can sign our .modl files for use in Ignition? What have I missed? Is there a way with module-signer? Have others run into this?
look at the IA module-signer code to see what constitutes a signed module, then write your own custom code to achieve that interfacing with the HSM/vault.
ignore all of this, stop using a "real" code signing certificate, and just generate your own
Module signing as it exists in Ignition is a pointless half implemented idea. It achieves essentially nothing and does not require the use of a fancy code signing cert from a public CA.
I use a Yubikey Neo and a NitroKey HSM. It was a bit of a pain to transfer my private key to the Nitrokey, fwiw. Currently using the maven module-signer from a command line via ant. The gradle project I was playing with stalled for lack of priority (my lack of copious free time, natch).
Since the gradle plug-in calls the maven module-signer classes, it just needs additional argument handling. Which, from a brief look, is precisely what Brian has added.
(I use the OpenSC libraries, which seemlessly handles whichever key happens to be plugged in.)
Hmmm. My module-signer folder has this git log --pretty:
commit 1b55e1766299feb4cb100626d43261d7872c8671
Author: Philip J. Turmel <philip@turmel.org>
Date: Tue Nov 13 14:26:26 2018 -0500
Java 11 Support, not backwards compatible
commit 7a3df1e5f313d07c1b6aa105f92908c41d93899a
Author: Kevin Herron <kevinherron@gmail.com>
Date: Tue Aug 30 07:20:10 2016 -0700
Add support for private keys from PKCS11 sources
This patch was generously provided by Phil Turmel
commit 58d0057557f2536a13914cb3eb37dc5799139cf5
Author: Kevin Herron <kevin@inductiveautomation.com>
Date: Thu May 19 08:48:06 2016 -0700
Add configuration for jar and assembly plugins
commit b0a0f3cba123052168a807273e27fedd394009fe
Author: Kevin Herron <kevinherron@gmail.com>
Date: Fri Mar 11 09:22:50 2016 -0800
Update README.md
{ older commits omitted }
That top commit was a patch from you, IIRC, locally applied.
When I looked at this last year, the gradle plug-in depended on module-signer-tools and called its signing implementation. It did not have its own implementation. Just had a thin wrapper to collect the necessary arguments.
That's all I thought it needed too way back when I first looked more closely at your GH issue and the code ... not so. The Gradle plugin calls a method in module-signer that sidesteps Kevin's PKCS#11 enhancement--cracking open the keystore (file- or HSM-based) and grabbing the private key.
I guess it would be fair to say for the signing operation itself, it is a thin wrapper. Fetching and unlocking the cert from the keystore, it's got its own implementation. Always has unless I am reading the git blame incorrectly.
Yeah, go look at the ModuleSigner class's main() function. The branch taken for PKCS11 is almost trivial (line 124). The actual module signer class is handed a private key "placeholder" produced from the PKCS logic.
You need a similar 4-line-or-so branch to assemble the PKCS args => keystore instead of the regular keystore.
Yep that's in my fork already. That's what I've been testing. Should have a draft PR up soon.
The other day I think I linked to a full diff of my fork against the upstream master branch but maybe not, I also had a few individual commit links in there. Maybe that made the extent of my WIP unclear.