Verification and Build Reproducibility for Java Releases, Version 0.9

Any Metrics release is provided in a compressed and gpg-signed tarball. How to verify such a gpg signed file is explained here. The following is concerned with the additional features Java and the Java JDK provides.

Java jars can be signed and timestamped. This is supported be JavaSE tools. An overview and further pointers can be found in Oracle's Java Tutorials.

Jar signing also generates a signed list of digests for each file that is part of the jar, which can be used for reproducing a build.

Definition: A Java build is reproducible when it can be build anew and results in identical byte-code (class files).

Reproducing a Java build needs sources, dependencies, and a Java JDK of at least the same version as the original one. Jars in Metrics products releases are signed and provide sources as well as the dependencies used for the build and the Git revision number of the released sources. All this together gives plenty of information to reproduce the build or detect that the release was tempered with in some way.

Simple List of Steps for Verifying Metrics Java Projects Releases

  • download tar.gz
  • verify gpg signature (steps for verification)
  • unpack the tar.gz file, i.e. tar xf <name>.tar.gz
  • cd to <name>-<version>/generated/dist/signed folder
  • quick verification: jarsigner -verify <name>-<version>.jar (Unless you imported certs earlier it will warn that the cert chain was not validated. That's ok. More important are the signatures and manifest entries.) For a more detailed explanation and guide see Oracle's Java Security Tools.

Steps for Reproducing the Released Classes

Here is a list of necessary things for reproducing the build with a short description about where to obtain them from.

  • source files: either provided from the release tarball or in the git repository. The git revision used for the release is part of the jar file's MANIFEST.MF. Look for Implementation-Version: 1.1.0-xxxxxxx the xxxxxx contain the used git revision.
  • dependencies: these are part of the release tarball.
  • build.xml: also part of the tarball or the git repository
  • ant: An Ant installation of a version close to the one used for the release, which can be found in MANIFEST.MF Ant-Version: Apache Ant x.y.z.
  • Java JDK: The JDK version that was used in the release should also be part of the MANIFEST.MF JDK-Version: 1.8.0_111XXXXXXXX

When testing these steps: the Ant version may differ, whereas the version and provider of the JDK usually need to match in order to produce the same bytecode. The operating system is unimportant (it's Java after all). For example, I verified a release produced on OS X on a Linux flavor using Ant of a different minor version.

Having sources, Ant, and an appropriate JDK at hand the classes can be build and compared to those in the release jar. This can be done with a diff-tool of your choice. Or, by signing the produced jar and comparing the resulting digests.

Further resources

A very simple helper script I have for release verification.

Last modified 15 months ago Last modified on May 25, 2018, 12:52:05 PM