Signed bundles and protecting against malicious code

Overview

The Eclipse platform faces a problem common to any program that can be extended by executable code: the potential that the extension code may be malicious. To address this concern, Eclipse embraces and extends the facilities built into the Java runtime in order to do two things:

  1. Authenticate the source of executable code in bundles
  2. Authorize the installation and runtime behaviour of code

Authenticating code packaged in a bundle

The first step towards protecting the platform from malicious code is 'authentication', or proving the identity of the person who is distributing the code in a bundle. This is facilitated by the use of a Public Key Infrastructure (PKI), where users are issued public certificates and private keys that uniquely identify them. Another common and well know use of certificates is the SSL protocol by which secured web sites are accessed.

The mechanism by which the authentication step is enabled is through the use of 'digital signatures' created by the code distributor, using a private key and a process called 'signing'. When consuming code and validating the identity of the code signer, the digital signatures are input - along with the signers public key - to an inverse process called 'verifying'.

In the Java platform, digital signatures are built into the Jar packaging format. A signed jar contains additional files alongside the META-INF\MANIFEST.MF that contain the information required to verify the signature, specifically a signature file (<SIGNERNAME>.SF) containing cryptographic digests of the resources contained in the Jar, and a block file (<SIGNERNAME>.RSA or <SIGNERNAME>.DSA) containing the signature data and associated certificates.

Using this information, one can verify that specific resources in a Jar file have not been tampered with and also establish the identity of the signer. The runtime then determines the 'trustedness' of the signer, the default behaviour being to check for the presence of the signer certificate (or one of its ancestor certificates) in the JRE's 'cacerts' file.

For more general information on PKI, Certificates, Digests, and Signatures:

For more specific information on signing in the Java platform:

Signing code packaged in a bundle

In order to sign a bundle, an Eclipse developer has a handful of options:

  1. The Java command line tool, 'jarsigner'

    Jarsigner is a tool that ships with the Java SDK, and can be used to generate signatures on Jar files. For more information see the SDK documentation at:

    http://download.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html

  2. A custom ant task, <signjar>

    The 'Ant' build tool has a built-in task for automating the signing of code. For more information, see the related Ant documentation at:

    http://ant.apache.org/manual/Tasks/signjar.html

  3. The Eclipse 'export deployable plug-ins and fragments' functionality

    Eclipse ships with the ability to export Eclipse plug-ins and sign them at the same time. When exporting deployable plug-ins and fragments, there is a JAR Signing tab available. In the tab, the exporter can specify a KeyStore (a password-protected key storage) containing a private key to use for the signing.

Verifying signed code packaged in a bundle

As with generation of signed bundles, verification of signed code can be done by an Eclipse developer in several ways:

  1. The command line, 'jarsigner'

    The Jarsigner tool is also capable of verifying signatures when passed a -verify option. For more information, consult the Java SDK documentation.

  2. Programmatically via the core Java APIs.

    There are several APIs in the Java API which allow interaction with signed Jars. For example, the java.util.JarFile API can be passed a parameter which enables verification of signatures. Several consumers of this API, including the URLClassLoader, pass this parameter to cause verification to occur. Unfortunately, little detail beyond the success or failure of verification is available through the core APIs.

  3. Programmatically via the Equinox 'signedcontent' APIs

    In 3.4, several interfaces for inspecting the signer details of a bundle have been introduced into the Equinox bundle (org.eclipse.osgi). Starting with the SignedContentFactory, a developer can programmatically inspect the entries in a bundle to see signers, timestamps and whether a code signer is trusted or not. For more information see the javadoc for the org.eclipse.osgi.signedcontent package of the org.eclipse.osgi bundle.

Authorization of signed code

Once the signer(s) of code packaged in a bundle is established via authentication, the next step to perform is 'authorization'. Authorization is the process by which the system decides whether a piece of code should be able to perform a specified action. Although the Java runtime supports a fine grained runtime permission model, Eclipse also supports two additional enforcement points with respect to signed code packaged in bundles. This gives Eclipse platform deployers a range of security solutions that allow tradeoffs to be made between flexibility and complexity versus manageability and performance. In Eclipse 3.4 or later, authorization based on signatures can be performed:

  1. When code is installed by the provisioning system

    For several previous releases and in the P2 provisioning framework, Eclipse has the ability to check signatures as bundles are provisioned into the system. As the provisioning system encounters bundles, it automatically performs authentication of the code signer and will prompt if a signer is not trusted according to the system configuration. The end user will be presented with a list of untrusted signers, and choosing to trust will allow the bundles to be installed into the platform. Since version 4.23, PGP signatures in P2 metadata are supported, in addition to the signatures created with Java's jarsigner.

  2. When code is loaded by the runtime

    Since 3.4, the Equinox runtime has had the ability to check the signature of code as it is loaded. The benefit to this feature beyond checking signatures during provisioning is the ability to dynamically remove trust and disable code should an exploit be exposed in deployed code. In order to enable signature-based authorization at load time, the following VM argument must be passed:

    	-Dosgi.signedcontent.support=authority
    

    See the runtime options page for more information about the osgi.signedcontent.support runtime variable.

For more information on security topics related to Eclipse and Equinox, see the site: