Self signed module not loading

I've tried to follow the module signing instructions here:

https://docs.inductiveautomation.com/display/SE/Module+Signing

and, along with help some other resources, managed to get my module signed but it won't load on a system that is not in developer mode.

Certificate for module REST-Alarm-Notification-signed.modl not trusted

I'm wanting to use a self signed module for internal use as described in the docs:

Modules can be signed using either a real code signing certificate obtained from a Certificate Authority or using a self-generated and self-signed certificate. What kind of certificate you use to sign your module depends on the level of assurance you want to offer your end users. If you're building a module for internal use within your company, using a self-signed certificate may not be an issue.

I'm assuming I've missed some important step. Are there some other resources available to help diagnose this and get it working?

1 Like

If you go to the module page in the configuration section of the gateway and scroll to the bottom is there not an option to install/trust your module? Can you show us some screenshots of what you're seeing?

1 Like

I see the self signed module warning and allow that but then installation fails.

com.inductiveautomation.ignition.gateway.modules.ModuleVerificationException: module verification failed
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.verifyModuleSignatures2(ModuleManagerImpl.java:1617)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.loadModule(ModuleManagerImpl.java:1314)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl$2.call(ModuleManagerImpl.java:775)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.executeModuleOperation(ModuleManagerImpl.java:958)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.installModuleInternal(ModuleManagerImpl.java:748)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl$InstallCommand.execute(ModuleManagerImpl.java:1917)
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl$Receiver.receiveCall(ModuleManagerImpl.java:1870)
at com.inductiveautomation.ignition.gateway.redundancy.QueueableMessageReceiver.receiveCall(QueueableMessageReceiver.java:47)
at com.inductiveautomation.ignition.gateway.redundancy.RedundancyManagerImpl.dispatchMessage(RedundancyManagerImpl.java:1030)
at com.inductiveautomation.ignition.gateway.redundancy.RedundancyManagerImpl$ExecuteTask.run(RedundancyManagerImpl.java:1098)
at com.inductiveautomation.ignition.common.execution.impl.BasicExecutionEngine$ThrowableCatchingRunnable.run(BasicExecutionEngine.java:544)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException: signature verification failed
at com.inductiveautomation.ignition.gateway.modules.ModuleManagerImpl.verifyModuleSignatures2(ModuleManagerImpl.java:1609)
... 16 common frames omitted

Looks like a signing issue. The cert generation process is quite complicated. I've used some generic instructions from various sources to do that and I've probably messed that up. Can you direct me to some instructions about how to do this properly so that it will work with Ignition?

What does this mean?

There's a module signing utility that does all of this for you: GitHub - inductiveautomation/module-signer: A utility that signs modules for use in Ignition

1 Like

I've used the module signing utility as described in the documentation and it succeeds without an error but I have used instructions found in various places to generate the certs and convert them to the required format and I think I have done this incorrectly. What I'm asking for is pointers to some guidance on how to do that correctly. I.e steps 1 & 2 from the docs:

What you'll need:

  1. code signing certificate.
  2. the full certificate chain, in the correct order, in p7b (PKCS7) format.
  3. the IA module signing tool or a tool that is capable of doing the equivalent.

I got it working. Here's the procedure I used in Linux (Fedora 37).

In each step enter the requested information as prompted.

1 - Generate a Certificate Authority (CA) key

$ openssl genrsa -des3 -out rootCA.key 4096

Give the root CA key a password and don't forget it!!

2 - Create an x509 CA certificate (DER encoding)

$ openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3652 -out rootCA.crt

3 - Creating a keystore and key for signing

$ keytool -genkey -alias codesign -validity 3652 -keyalg RSA -keysize 4096 -keystore codesign-keystore.jks

4 - Generating a certificate signing request (CSR) with the new keystore

$ keytool -certreq -alias codesign -file testsign.csr -keystore codesign-keystore.jks

5 - Generate a x509 signing cert and key pair by signing the CSR with the CA certificate

code_sign_cert.conf:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com

$ openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in testsign.csr -out testsign.crt -days 3652 -CAcreateserial -extfile code_sign_cert.conf

6 - Convert the signed cert to pkcs7 format

$ openssl crl2pkcs7 -nocrl -certfile testsign.crt -out testsign_pkcs7.p7b -certfile rootCA.crt

7 - Import the signed certificate into the keystore

$ keytool -import -trustcacerts -alias codesign -file testsign_pkcs7.p7b -keystore codesign-keystore.jks

8 - Sign module using this keystore

$ java -jar ../module-signer/module-signer.jar \
    -keystore=./codesign-keystore.jks \
    -keystore-pwd=<secret> \
    -alias=codesign\
    -alias-pwd=<secret> \
    -chain=testsign_pkcs7.p7b \
    -module-in=my-module-build/target/My-Module-unsigned.modl \
    -module-out=my-module-build/target/My-Module-self-signed.modl

Refererences:

2 Likes