Module Signing Using Certificate From Certificate Authority

Has anyone successfully used a certificate from a CA to sign a module?

I have acquired a Certificate from Digicert ONE and attempting to use DigiCert Keylocker to get the private key. I am using openssl and jarsigner to actually sign the module.

I have also attempted to use the signer-master tool (GitHub - inductiveautomation/module-signer: A utility that signs modules for use in Ignition) in conjunction with my acquired certificate to sign my module. However, I don't have access to the private key which is preventing the module from being signed.

I am pretty much at a loss. What options/ tools are recommended/ available for signing a module using a certificate that was created in a PKI environment where private keys are not accessible?

For further context, I was able to self-sign the module no problem, but I assume that was because I was the one who created the certificate as well as the private key.

For clarity, we are able to use the provided key with PKCS11 mappings in openssl and jarsigner tools. However, the configurations don't seem to map to the module-signer tooling.

For example, we could sign an individual JAR file succesfully with

jarsigner -keystore NONE -storepass NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg "pkcs11properties.cfg"  -digestalg SHA-256  -signedjar "web-1.0.0.jar" "web-1.0.0.jar" key_514152874  -tsa http://timestamp.digicert.com -tsadigestalg SHA-256

However, it appears that ignition is just taking a signature of each file, and including that in the module and not signing the jars. So we attempted to use openssl to generate hashes like:

openssl dgst -engine pkcs11 -keyform engine -sha256 -sign "pkcs11:object=key_514152874;type=private" common-1.0.0.jar | base64 -w 0

Using the output from the above to manually write to the signatures.properties file, the module fails to load (figured this as a manual process longshot)

Note, the certificates.p7b file included in the module is able to successfully verify the files based upon the hash present ...

Thanks in advanced!

Use the module-signer utility IA provides. (maven/github). It can perform PKCS11 module signing from the command line. (I do it all the time shelled from my ant builds.) Confirmed to work with my YubiKey and NitroKey devices. (Not yet incorporated in the gradle plug-in. Use the command line in the interim.)

Not sure how PKCS11 works with Digicert, but they should be providing the information needed to populate a pkcs11.cfg file.

You can also study how the module signer works, if you need to re-implement in a unique environment.

FWIW, a snippet from my ant build.xml:

<java fork="true" jar="${basedir}/../module-signer/target/module-signer-1.0.0-SNAPSHOT-jar-with-dependencies.jar">
	<arg value="-pkcs11-cfg=${basedir}/pkcs11.cfg"/>
	<arg value="-alias=Certificate for PIV Authentication"/>
	<arg value="-keystore-pwd=${keystorepw}"/>
	<arg value="-alias-pwd=${keystorepw}"/>
	<arg value="-chain=${basedir}/autopros-code-signer.p7b"/>
	<arg value="-module-in=${basedir}/Build/modules/${module.name}-${asbuiltversion}-unsigned.modl"/>
	<arg value="-module-out=${basedir}/Build/modules/${module.name}-${asbuiltversion}-v81.modl"/>
</java>

and the corresponding pkcs11.cfg:

name = OpenSC
library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
description = OpenSC PKCS11 Provider

In the above invocation ${keystorepw} is the device's PIN.

1 Like

Thanks for the quick response!

There were multiple issues in a couple different places that was causing all the headache.

Anyway, I successfully signed the module using the IA tool and installed it on my trial gateway. The module still appears as "self-signed", is this expected behavior? The namespace was changed to reflect the name given to Digicert when we applied for the certificate so I know that it is at least using the correct certificate .

Also for anyone else looking to do something similar, it wasn't obvious (at least to me) that there even was a -pkcs option in the IA signing tool.

The end result looked something like this:

java -jar module-signer.jar \ 
	-alias=<key_alias>\
	-chain=<pathToMyp7b> \
        -pkcs11-cfg=<path_to_pkcs.cfg>  \
	-module-in=<path-to-my-module>/my-unsigned-module.modl \
	-module-out=<path-to-my-module>/my-signed-module.modl

where the -pkcs parameter replaced the parameters related to the keystore

This happens if:

  • The CA for the cert isn't well-known to java, or

  • The chain file wasn't complete, or

  • The chain file wasn't in order (surprisingly common to find reversed).

Ignition doesn't care, by the way. I switched to my own CA last year because many CAs are making it difficult to use local CSRs. (Vendor lock-in. grumble...grumble...)

Just to close the loop on this, my p7b file was built using only one of the three certificates provided by DigiCert. After rebuilding the p7b with all included certificates and re-deploying to ignition everything works as expected.

Thanks again, Phil !!