Signing Commands

Code signing commands emulate functionality of standard tools. They are used as an alternative to the integration with standard tools.

UCLClosedUnbound Command Language provides the following commands:

ucl sign Command

The specified --out-format defines the type of signing applied to the input:

OpenSSL DGST Mode

Applicable when the ucl sign command is set to produce BIN (default), HEX, or BASE64 output.

ucl sign <-u [--uid ] |-n [--name ]> signing-key // The UID or name of RSA or ECC signing key -i [--input ] input-file // File to be signed [--in-format format] // Input file : BIN (default), HEX, BASE64 [--input-hash] // Indicates that the input data is hash -o [--output ] signature // Output file [--out-format signature-encoding] // Output format: BIN (default), HEX, BASE64 [--hash <Supported HASH Options>] // default: SHA1 --pkcs7 // Output is PKC#7 file --detached // Generate detached PKC#7 signature

In the following example, we generate the signing key, sign the test file, and verify the result:

  1. Generate a signing key and export its public part to a PEMClosedBase64 encoded DER wrapped by "--- BEGIN <type> ---" and "--- END <type> ----" file (VERIFY-KEY.pem) that will be used to verify the signature:
  2. ucl generate -t ecc --curve p256 -n SIGN-KEY -o VERIFY-KEY.pem

  3. Sign a BIN file:
  4. ucl sign -n SIGN-KEY --hash sha512 -i ./test.bin -o ./test-bin-signature.bin

  5. Verify the integrity of the test.bin file:
  6. openssl dgst -sha512 -verify ./VERIFY-KEY.pem -signature ./test-bin-signature.bin ./test.bin

GPG Detach-Sign

Applicable when the ucl sign command is set to produce PGPClosedPretty Good Privacy - PKI implementation or PGPClosedPretty Good Privacy - PKI implementation-ARMOR output.

  • You must use an RSA key. The hash of the input file is padded using the PKCS1 padding.
  • It is available on the Linux and MacOS client appliances only.
ucl sign <-u [--uid ] |-n [--name ]> signing-key // The UID or name of the RSA signing key -i [--input ] input-file // File to be signed -o [--output ] signature // Output file --out-format signature-encoding // Output file format: PGP, PGP-ARMOR [--hash <Supported HASH Options>] // default: SHA1

Example:

In this example, we generate the signing key, sign an XML file, and verify the result:

  1. Prepare the signing key for signing and verification:
    1. Generate RSA signing key SIGN-KEY and export its public part to the PGPClosedPretty Good Privacy - PKI implementation-formatted file public_SIGN-KEY.pgp:
    2. ucl generate -t rsa -n SIGN-KEY -o public_SIGN-KEY.pgp --format PGP

    3. To perform verification of the signed material, import the key to the GPGClosedGNU Privacy Guard - PGP cryptography implementation keyring using the --allow-non-selfsigned-uid option:
    4. gpg --import --allow-non-selfsigned-uid public_SIGN-KEY.pgp

      Note
      Starting with the CORE release 2.0.2001, ucl export --format PGPClosedPretty Good Privacy - PKI implementation exports self-signed public key. No need to specify --allow-non-selfsigned-uid.

  2. Use the signing key to sign a test file (test.xml). Convert the binary signature to ASCII format (PGPClosedPretty Good Privacy - PKI implementation-ARMOR) in the output file test.xml-signature.asc:
  3. ucl sign -n SIGN-KEY --hash sha256 -i ./test.xml -o ./test.xml-signature.asc --out-format PGP-ARMOR

  4. Verify that the content of the file matches the signature. This step uses the public part of the signing key stored in the PGPClosedPretty Good Privacy - PKI implementation key repository in step#1.2:
  5. gpg2 --verify ./test.xml-signature.asc ./test.xml

ucl sign-code

In this case, the ucl sign command signs the following files:

  • .appx
  • .cab
  • .cat
  • .dll
  • .exe
  • .js, .vbs, .wsf
  • .msi, .msp, .mst
  • .ocx
  • .ps1
  • .stl
  • .sys
ucl sign-code
--file <file name>
-u [--uid] | -n [--name] <crypto object> // name or UID of key or certificate
[-d [--desc] "<application title>" // default: <file name> [ -t [--timestamp] <timestamp URL>] // default: none [--hash <Supported HASH Options>] // default: SHA1
  • crypto object - must be name or UID of a key or a certificate. Both the signing key and its certificate must be present in the partition.
  • application title - the application's name that will appear in the "Do you want to run/install this application" prompt when installing the application. Usually, it is the name of the application.
  • timestamp URL - URL of the timestamp service provider.
  • Note
    Timestamping allows extending the validity of the signed package indefinitely. According to Microsoft's best practices blog, "If you do not timestamp your code, the signature will be treated as invalid upon the expiration of your digital certificate. A signed, time-stamped package remains valid indefinitely, so long as the timestamp marks the package as having been signed during the validity period of the certificate."

Examples

Assume that the test partition has My Sign Cert attested by the self-signed My Self-Signed Root CA:

ucl list

Partition 0 test: 4 objects found
Certificate : UID=a99473e3b0329057 Name="My Self-Signed Root CA"
Certificate : UID=c2e739b01e573bbe Name="My Sign Cert"
Private RSA key : UID=3d18c64fe1a8c441 Name="My Sign Cert"
Private RSA key : UID=566b8c1c4fcd6fa8 Name="My Self-Signed Root CA"

ucl sign-code --file test.exe --name "My Sign Cert" \
-t http://timestamp.digicert.com

The file test.exe is successfully signed.

ucl verify-code - Windows

Syntax:

ucl verify-code
--file <file name>

Examples:

ucl verify-code --file test.dll

The file "test.dll" is signed and the signature was verified.

Troubleshooting

If the trust of the signing certificate cannot be confirmed, the following warning appears:

Error is: 0x800b0109.
A certificate chain processed but terminated in a root certificate which is not trusted by the trust provider.

Note
To mitigate this warning, install the certificate of the authority that signed the import certificate to the Cert:\currentuser\trusted root certificate authorities.

To examine the signature and the trust chain, proceed as follows:

  1. Navigate to the file in the Windows File Explorer.
  2. Click the right button and select the Properties.
  3. If the file has been signed, the Properties dialog presents the Digital Signature tab.
  4. In the Digital Signature tab, select the required signature and proceed to its Details.

ucl sign-rpm

Available on Linux-based CORE clients.

CORE supports signing the Linux RPMClosedFile format for software package distributed by RPM Package Manager package using RSA private key in the following use cases:

  • Using the RSA key generated by the CORE.
  • Using imported RSA Key.

Sign RPM Using Generated Key

The signing key may be specified by its UID, its name, or UID of the corresponding certificate. The CORE provides the signature's metadata.

To generate meaningful public PGPClosedPretty Good Privacy - PKI implementation information regarding the signing key, use meaningful UID name and description.

Prerequisites:

  • Key type: RSA.
  • The key must permit signing: Allow sign = true. This is true by default.
ucl sign-rpm -i [ --input ] < RPM file to be signed> [-o [ --output ] < The signed RPM file>] // if omitted, the input file is overwritten -u [--uid ] | -n [--name] <arg> // the name or UID of the key or certificate -p [--partition ] | -s [--slot] <arg> // partition that hosts the signing key

Example:

ucl list

Partition 0 test: 2 objects found
Certificate : UID=fb5cea2a8de568f6 Name="GPGkey"
Private RSA key : UID=04a315d5721a9709 Name="GPGkey"

ucl show -n GPGkey | grep sign

Allow sign = true

ucl sign-rpm -i ./test-package.rpm -u 04a315d5721a9709

The signed file test-package.rpm is successfully generated.

In the above example, we overwrote the input file test-package.rpm.

Sign RPM Using Imported Key

This option applies when the signing key and its certificate have been imported into CORE . Use this option if you want to include the metadata stored in the externally maintained certificate of the key.

Prerequisites for the imported key/certificate

  • Must be RSA.
  • Must allow signing.

The optional PublicKey.pgp file is the source for the signature's metadata. It must have PGPClosedPretty Good Privacy - PKI implementation PUBLIC KEY BLOCK that matches the private key used for signing.

ucl sign-rpm -i [ --input ] < RPM file to be signed> [-o [ --output ] < The signed RPM file>] // if omitted, the input file is overwritten -u [--uid ] | -n [--name] <arg> // the name or UID of the key or certificate -p [--partition ] | -s [--slot] <arg> // partition that hosts the signing key [--pgp-pub <CorrespondingPublicKey.pgp file>] // source of the signature metadata

Verify RPM Signature

Steps:

  1. As needed, export the corresponding public key into a PGPClosedPretty Good Privacy - PKI implementation-formatted file:

  2. ucl export -n GPGkey -f PGPClosedPretty Good Privacy - PKI implementation -o public-GPGkey.pgp

  3. Import the public key to the RPMClosedFile format for software package distributed by RPM Package Manager DB:

  4. rpm --import public-GPGkey.pgp

  5. Verify the signature:

  6. rpm -Kv ./test-package.rpm

    Header SHA1 digest: OK (9cdea49d0363c70b035e68a066a6a8366edf32d1)
    V3 RSA/SHA256 Signature, key ID c649f3ba: OK
    MD5 digest: OK (1bfde35e913d54731532d0538599b14e)