Tuesday May 20, 2014

Compact Profiles: Space and Security

Compact Profiles provide a way for developers and device manufacturers to package and update Java SE on space-constrained devices. Teams building software for those devices can trim the size of the embedded JRE by choosing a Compact Profile without items that are not used by their application. Additional details are present in Java Magazine’s March Issue, as well as the Java SE 8 launch videos “Developing Embedded Applications with Java SE 8 Compact Profiles.”

By shrinking the size of the JRE, we enable developers to use their existing Java skills in new areas and take advantage of hardware like the Raspberry Pi, the BeagleBoard, and many others. This post will cover a few aspects of Compact Profiles:

  • Comparisons between complete JRE and each profile
  • Threat modeling of a Compact Profile
  • Identifying and creating your compact JRE
  • Configuring, installing, and updating your compact JRE
  • Summary of compact profiles

Comparisons between the complete JRE and each profile

To see the various areas that Java runs in, here is a chart of sizes:

 Version Approx. Size Installed
Used for
Most developers use this.
Developers building Java applications and/or profiling them with Mission Control.
Most client systems use this.
Clients running Java applications on their Windows/Max/Linux desktop.
Server JRE 8
Server systems, for running back-end processes or application servers. This JRE can run servlet containers and compile JSPs. It is smaller than the regular JDK because it does not contain the browser plug-in, Java Mission Control, or VisualVM.
Java SE Embedded 8

Embedded devices like the Raspberry Pi, BeagleBoard, etc.
Java SE Embedded compact 3
Embedded devices requiring Kerberos or remote monitoring like JMX, but not APIs like Swing, CORBA, and Java Sound.
Java SE Embedded compact 2
Embedded devices making use of SQL connectivity or XML processing, but not any functionality from compact3.
Java SE Embedded compact 1
Embedded devices requiring a minimal version of Java SE, but not any functionality from compact2.
Java ME Embedded
Varies based on highly constrained device.
Highly constrained embedded devices.

If you are working on an embedded device and wondering which profile you should use, please see the video “Choosing a Compact Profile for your Deployment.” It is also possible to mix-and-match certain items in different profiles through extensions.

Complete details for each profile, including API listing, are located on the Compact Profiles page and within JEP 161.

Threat modeling of a Compact Profile

Compact profiles also contain a different threat model than the typical JDK Conceptual Diagram. Although the runtime is similar from the application’s point of view, the profiles are defined by items that are NOT present. For example any risk or potential misuse associated with Java2D would be mitigated in the compact3 profile, which does not include that component.

The Server JRE is a similar example: by not even having the deployment components of RIAs and browser plugins, the risk is eliminated (servers typically do not use that functionality).

It is possible to reduce and mitigate other threats as well given the control that the device manufacturer or operator has over installation/updates of the JRE. For example after creating a compact profile, one could decrease the threat model’s scope of Spoofing and likely Information Disclosure by updating the default keystore to remove everything except known-needed roots and then requiring encryption.

Identifying and creating a Compact Profile

JDK 8 provides a new tool called JDeps that can look at a collection of JAR and CLASS files and report on which compact profiles are used. When using JDeps to evaluate profiles, the report is transitive: if all your code fits in compact1 but you require something else that needs the larger compact2, then you must either use compact2 or remove the offending component.

Example usage of this is:
jdeps -profile filename.jar

filename.jar -> C:\Program Files\Java\jdk1.8.0\jre\lib\jce.jar (compact1)
filename.jar -> C:\Program Files\Java\jdk1.8.0\jre\lib\rt.jar (Full JRE)
filename.jar -> AnotherPackage.jar
   your.package (filename.jar)
      -> com.sun.deploy.config   JDK internal API (deploy.jar)
      -> java.io                 compact1
      -> java.lang               compact1
      -> java.lang.invoke        compact1
      -> java.math               compact1

Additional details can be found in Jim Connors’ blog, Compact Profiles Demonstrated.

JDeps can also be used to identify reliance of non-spec internal JDK APIs that are subject to removal, so that you can move to the appropriate public replacement.

Creating, configuring, and updating your Compact Profile

Once you have identified the appropriate profile, you can create a compact profile that will run on the target device.

  1. Download the version of Java SE Embedded for your target platform.
  2. Unzip the version that you downloaded into its usual ejdk folder.
  3. Use the included bin/jrecreate command to create the profile.
    This step requires a JAVA_HOME variable, which should point to your system’s java installation and not anything related to the target device.

For non-embedded OpenJDK, the profiles must be built separately on Linux.


  • To create the bare minimum compact1 profile:
    jrecreate -d ~/compact1 -profile compact1
  • To create the bare minimum compact1 profile that also has the sun elliptical curve extension:
    jrecreate -d ~/compact1WithEC -profile compact1 -x sunec

Once created, simply copy the newly created folder to your device and run it like any other application.

Configuring your Compact Profile

Once the compact profile has been created, it contains several noteworthy items beyond the JRE itself. One file in particular, called bom, lists the bill of materials for this compact JRE. By having that file, you and any subsequent users will be able to see precisely what went into this profile, when it was created, and other useful piece of information.

You may then customize the information as you would any other JRE. All configuration files are present, such as such as network configuration and proxy information, timezone data, etc.

Updating your Compact Profile

Any compact profile that you create is outside the scope of typical package management systems like RPM. For a device manufacturer, there are many commercial systems which exist to handle this. It is recommended to have a mechanism for patching devices, should the need arise.

Although devices may perform minimal operations, it is reasonable to plan ahead for software updates of your applications, the compact Java profile, as well as any underlying operating system and its libraries.


Compact profiles provide a way to trim down the Java runtime in order to fit on embedded devices, either as a system component or part of an application. Not only can compact profiles shrink the size of a Java runtime down to 11MB, it also decreases the potential attack surface.

Thursday May 01, 2014

Deployment Rule Set by Example

Recently I encountered a situation whereby a System Administrator needed to adjust thieir systems to run a specific RIA on an older version of Java. By using Deployment Rule Sets, we were able to achieve the desired outcome. The specific RIA ran using the older version of Java with no prompts to the end users, while all other RIA applications used the latest, most secure version of Java.

This post is intended for System Administrators managing a white list within an organization.

Assessing the environment

In this particular case, the RIA itself was designed to run on Java 6 update 31 (released in February 2012, but public updates for Java SE 6 ended in February 2013). That also means that it does not adhere to the security requirements introduced in a recent Java SE 7 Critical Patch Update. Because this RIA was known to be safe and necessary for business operations, the goal was to be able to execute it with no prompts.

Installing multiple versions of Java

When delegating RIAs to use older Java versions, it is necessary to have at least two installations available:

  1. The latest Java version, which will be used by default except in cases where you configure it to delegate to the older version. We installed this as the default patch-in-place.
  2. The specific older versions needed by the RIA, which will only be accessible through your Deployment Rule Set. We installed this as a static installation to prevent any interference in case that a different Java SE 6 version had to be installed for something else.
    1. Although older versions are not updated with the latest security patches and not recommended for use in production, the Deployment Rule Set mitigates the definition of "in production" because the older JRE is only accessible from explicitly whitelisted areas.

Information about these installation types can be found within a previous post, Managing Multiple Java Versions. Comprehensive documentation is provided by Oracle about silent installation switches for package management as well as disabling third-party sponsors.

Once items were installed, we had two noteworthy locations on the Windows desktops (others may be available as well, but these are the important ones):

  1. C:\Program Files\Java\jre7
  2. C:\Program Files\Java\jre1.6.0_31

Creating the Deployment Rule Set

Instructions on creating a Deployment Rule Set are available in the post Introducing Deployment Rule Sets or in the complete Deployment Rule Set documentation.

The actual deployment rule set used looks like:

<!-- Example Deployment Rule Set that allow a desktop administrator to control end-user's execution of browser applets.
  See http://docs.oracle.com/javase/8/docs/technotes/guides/jweb/security/deployment_rules.html -->
<ruleset version="1.0+">
        <id location="https://java.com/" />
        <action permission="run" version="SECURE" />
        <id location="http://internal.example.com/" />
        <action permission="run" version="1.6.0_31" />

In this example, we were able to identify and test each item. For example, the first rule checks that users could run the normal Java.com detection applet without any prompts. That demonstrated the correct setup of the DRS. Once successfully set up, the second rule allowed us to target their application.

Ensure the DeploymentRuleSet.jar is signed correctly for each Java installation

Most certificates from Certificate Authorities should work out of the box. The certificate used to sign your Deployment Rule Set must be trusted by each Java installation.

After your Deployment Rule Set is in place (in the documented area), the easiest way to check is to look at the control panel. Instructions for checking this are in the previous post, Introducing Deployment Rule Sets, under the “Verify usage of your rule set on a client desktop.”

Importing certificates into the older Java version

Although most administrators do not need this step, sometimes the older JRE does not contain the newer root certificate. In that case, it is necessary to locate the CA’s root certificate and explicitly import it:

"C:\Program Files\Java\jre1.6.0_31\bin\keytool" -importcert -keystore "C:\Program Files\Java\jre1.6.0_31\lib\security\cacerts" -alias AuthNameNoSpaces -file TheRootTheyProvided.cer

Once we had the root’s certificate inside both keystores, the RIA launched correctly on the older Java 6.

Verifying "is this working right"

Testing your Rule Set involves opening the RIA and verifying execution. Other system tools will help check and verify any assumptions. In addition to launching RIAs like the Java.com detection applet, the regular Task Manager will help understand which versions are getting launched.

Within the basic Task Manager, the Processes tab can show a command line column. In the case that you are launching a different version, you can show the Command Line column. In this screenshot, I’ve shrunk the view but it’s easy to see what I am running.

Screenshot of command-line in Win7 task manager

There are other tools available to view a process chain as well, where you will see a chain that looks like:

  • iexplorer.exe
    • jp2launcher.exe
      • java.exe (from the default JRE installation area)
        • java.exe (from your targeted JRE usage area)

Automating Package Installation

Once the item was identified as working, we were able to integrate the previous silent installation switches to roll the installations out onto different computers.

Most users or members of staff can run basic installers or scripts as needed. Large enterprises with desktop management systems often combine silent installation switches and customization commands (like the keytool import) with MSI creators, and then roll a single file out for installation.

I will refrain from discussing package creation and roll-out in detail. Use the right mechanism that works within your organization.

Reminder about external distribution

The Deployment Rule Set feature is intended for organizations to manage their own configurations. It is not meant as a way to simply "whitelist everything just so warning dialogs go away," "force everyone to never update," or "external users please download this file onto your system to use this application." By default, specifying the version="SECURE" attribute is best unless you know specific reasons restricting compatibility to a specific JRE version.

Publicly distributed Deployment Rule Sets found to contain insecure "whitelist everything" configurations may have their signing certificate blacklisted from future use of Deployment Rule Sets.

Additional Helpful Information

Appendix: Debugging if things to not work as expected

System Administrators new to Java may find the Java console useful to understand what is happening. Most users neither turn on nor see this console.

By turning the console on in the Java control panel, we were able to see execution.

Screenshot of java console

The first line in that file indicates the current version in use: JRE 1.8.0-b132. This is clearly not 1.6.0_31, meaning that it matches the first rule.

When we began using the Deployment Rule Set that delegated to Java 6 update 31, two major things happened:

  1. In the Task Manager process tree, two Java processes appeared. The first was the latest Java, the second was the older version connected to this process.
  2. Because we had the Java console turned on, two consoles appeared: one for each version.

If you press ‘5’ on that console, it will output a significant amount of log information. I won’t paste a sample log here because they can get long, but the really interesting parts look like:

 Sample from log
What it tells us
 Using JRE version 1.8.0-b132 Java HotSpot(TM) 64-Bit Server VM  At the top, this tells us which version is currently in use.
 Lines beginning with “ruleset:”
ruleset: RuleSetParser.parse() returning 2 rules:
 These tell what is happening with the DRS, isolated from other information.
 Lines that talk about “ruleset” and “location”
ruleset: finding Deployment Rule Set for
        title: Java Uninstall Applet
        location: https://java.com/applet/JavaRemovalTool/launch.jnlp
        jar location: https://java.com/applet/JavaRemovalTool/JavaRemovalTool.jar
        jar version: null
        isArtifact: true

 The location information helps me understand if I told the ruleset to whitelist the right place.
Sometimes, though not often, the browser URL and actual application URL are different.
In the example to the left, both are on https://java.com
Although my browser visits an area, /en/download/installed.jsp the actual files are hosted in /applet.
That means copying from my browser’s address bar would not have worked.

Appendix: Identifying applications by Certificate Hash or Location

The two primary ways of creating a deployment rule are by location or certificate hash.

  • Certificate hashes help identify a publisher. For example I could automatically run Oracle RIAs by creating a rule to run RIAs whose certificate hash is 794F53C746E2AA77D84B843BE942CAB4309F258FD946D62A6C4CCEAB8E1DB2C6.
    This rule would take effect regardless of where the RIA was hosted.
  • Location identifies where the RIA (specifically its JAR files) is hosted. This is sometimes easier to copy from a browser’s address bar and can be used in cases where the RIA publisher did not actually sign the RIA.

If the RIA uses LiveConnect (javascript integration), you must create a Location rule to whitelist the hosting domain and accept the LiveConnect calls.

Within the Java Console, there are also ways to locate both of those identifiers.

  • security: SHA-256Certificate finger print: Long certificate hash
  • basic: Plugin2ClassLoader.addURL parent called for http://url.example.com/path/someFile.jar

Those will help identify the items that the RIA plugin is seeing, so then you can look for one of the following messages:

  1. ruleset: Rule hash matches certificate hash (or a similar message about location)
  2. ruleset: no rule applies, returning Default Rule

Science Duke
This blog contains topics related to Java SE, Java Security and Usability. The target audience is developers, sysadmins and architects that build, deploy and manage Java applications. Contributions come from the Java SE Product Management team.


« May 2014 »