These docs are for v5.0.0. Click to read the latest docs for v7.5.0.

Bundle Signing

Before switching ESF to production mode, application bundles developed by customers must be signed.

๐Ÿšง

ESF bundles are already signed by Eurotech and do not require to be signed by the customer.

Certificate Generation

Public Key Infrastructure (PKI) certificates can be created in different ways:

  • Self-signing the public key (self-signed certificate)

  • Signing the public key with a company's certificate chain

  • Sending a Certificate Signing Request (CSR) to a trusted Certificate Authority (CA)

For code signing the first two options are inexpensive. Most of the times a self-signed certificate is just enough to get started.

Self-signed Certificate

A public/private key pairโ€‹ and the associated self-signed certificate can be created using the keytool command-line utility. This utility is available, free of charge, from any Java Development Kit (Oracle JDK, OpenJDK etc) for all operating systems.

๐Ÿ“˜

The example below makes use of ${} to denote a placeholder that will be replaced by an actual value. The notation is the same used in shell scripts to expand the variable between braces.
For example ${keystore_file} can be replaced by BundleSigningKeystore.ks.

Please note that the generated keystore contains the private key used to sign your code.
The keystore and the private key are protected by passwords (see below).
Keep these passwords and the keystore in a safe place.

  1. Use keytool to generate a keystore containing the new public/private key pairโ€‹ and the associated self-signed certificate:
# Note: key_pass and keystore_pass are respectively the password of the keystore
# and the password of the private key.
# Keep these passwords and the keystore in a safe place.

keytool -genkey -noprompt -trustcacerts -keyalg RSA -keysize 2048 \
-alias ${cert_alias} -dname ${dn_name} -keypass ${key_pass} \
-keystore ${keystore_file} -storepass ${keystore_pass} \
-validity ${cert_validity_days}

where:

  • ${cert_alias} is the alias for the new certificate.
  • ${dn_name} is the Distinguished Name of the new certificate (see below).
  • ${key_pass} is the password to be set for the new certificate.
  • ${keystore_file} is the filename of the new keystore.
  • ${keystore_pass} is the password to be set for the new keystore.

๐Ÿ“˜

A valid Distinguished Name (dn_name) can be the following:
CN=www.companyname.com,O=Company Name,C=US

Commas (,), quotation marks (") and semicolons (;) appearing in the certificate Distinguished Name (DN) must be escaped using the backslash (\) character.

  1. Optionally, check that the newly created certificate is in the keystore:
keytool -list -v -alias ${cert_alias} -keystore ${keystore_file}

Import the Certificate in ESF

The certificate that will be used to verify the bundles signature must be first imported in the ESF keystore. The location of the ESF keystore in the gateway filesystem is /opt/eurotech/esf/kura/certificates.ks.
There are two ways the bundle signing certificate can be added to ESF:

  • At any time from the Settings menu of the Everyware Gateway Administration Console Web UI
  • Before the very first ESF boot adding it manually to the ESF keystore.

Continuing the example of the previous section, the bundle signing certificate must be first exported by the bundle signing keystore:

# Note: the certificate will be exported to the file denoted by cert.file.
# The certificate is public and does not contain any secret.
# You will need the password of the keystore and the password of the private key.

keytool -export -v -keystore ${keystore_file} -alias ${cert_alias} \
-file ${cert_file} -storepass ${keystore_pass} -keypass ${key_pass}

Import the Certificate from the Administration Console

This method can be used at any time to quickly add a bundle signing certificate to ESF.
The certificate exported in the previous section is in DER format, while the Administration Console only accepts certificates in PEM format.

The exported certificate can be converted using the openssl utility:

openssl x509 -inform der -in ${cert_file} -out ${cert_file_pem}

The certificate (in PEM format) can then be added to the ESF keystore from Settings | Application Certificate in the Administration Console:

2312

Import the Certificate Directly in the ESF Keystore

The bundle signing certificate can be directly imported in a keystore that will replace the ESF factory keystore located at /opt/eurotech/esf/kura/certificates.ks on the gateway filesystem.

๐Ÿ“˜

This can be done only before the very first ESF boot regardless whether ESF is running in development or production mode.
If the ESF keystore located at /opt/eurotech/esf/kura/certificates.ks is replaced after the very first boot, ESF will detect that the keystore has been tampered and will refuse to boot.

For security reasons, the ESF factory keystore located at /opt/eurotech/esf/kura/certificates.ks is protected by an initial password which is not disclosed to customers. Due to this restriction, customers cannot directly import their certificates to the ESF factory keystore.

Eurotech provides an equivalent keystore, whose password is defaultPassword, containing the Eurotech certificates needed to verify the signature of the ESF runtime.
This keystore can be downloaded from this link.

The customer can import his own certificates in this keystore and replace the ESF factory keystore located in /opt/eurotech/esf/kura/certificates.ks.

๐Ÿšง

the value of the initial keystore password is written in plain text in the value of the kura.keystore.password property in /opt/eurotech/esf/kura/kura.properties. For improved security it is advisable to change the initial keystore password and modify the kura.keystore.password accordingly.

Having the keystore password stored in plain text in the kura.properties file represents a momentary vulnerability where the keystore could be tampered by an attacker before the very first ESF boot. For improved security it is advisable to boot ESF once before shipping the gateway.

๐Ÿ“˜

In all cases, ESF will change the initial keystore password to a randomly generated password at the very first boot. The new password is securely stored and cannot be recovered.

Continuing the example, the certificate exported from the the bundle signing keystore can be imported in another keystore with:

# Note: certificates.ks is the name of the keystore downloadable from
# https://s3.amazonaws.com/esf-resources/certificates.ks
# that will replace /opt/eurotech/esf/kura/certificates.ks

keytool -import -alias ${cert_alias} -keystore certificates.ks -file ${cert_file}

Update the ESF Security Policy

After adding the bundle signing certificate(s) to ESF, the security policy file has to be updated accordingly to allow the execution of genuine bundles.
Continuing the example, the new rule to be applied is the following:

<esf:policy>
  <esf:access>ALLOW</esf:access>
  <esf:conditions>
    <esf:condition>
      <esf:name>
        BundleSignerCondition
      </esf:name>
      <esf:value>
        ${dn.name}
      </esf:value>
    </esf:condition>
  </esf:conditions>
  <esf:permissions>
    <esf:permission>
      <esf:name>java.security.AllPermission</esf:name>
      <esf:values>
        <esf:value>
          *
        </esf:value>
        <esf:value>
          *
        </esf:value>
      </esf:values>
    </esf:permission>
  </esf:permissions>
  <esf:name>
    All permissions to bundles signed with this certificate
  </esf:name>
</esf:policy>

๐Ÿ“˜

As throughout the example, in the above XML snippet the placeholder ${dn_name} must be replaced with the actual Distinguished Name, for example "CN=www.companyname.com,O=Company Name,C=US".

JAR Signing

Bundles can be signed in the following ways:

  • Using the command line

  • Using Eclipse

  • Using Maven during the build process

Command Line Signature

To sign bundles from the command line, use the jarsigner command:

jarsigner -keystore file:${keystore_file} -tsa http://timestamp.digicert.com \
-storepass ${keystore_pass} -keypass ${key_pass} ${bundle_jar} ${cert_alias}

To verify the signature, use the following command:

jarsigner -verify -keystore file:${keystore_file} ${bundle_jar}

Bundle signature with Eclipse IDE

The Eclipse IDE provides a โ€‹bundle signing signature feature, abstracting jarsigner.
A simple guide on how to export bundle plugins and how to sign them is available here.