Wednesday, July 17, 2013

Tycho 10: Signing plugins and executables

Eclipse supports signed plugins and displays this information in its Installation Details. On Mac and Windows you might further want to sign your executable to get rid of potential warnings when launching your application. All this can be done automatically with tycho. To get a general overview how to build a product with tycho, see my previous tutorials on this topic:

Tycho Tutorials

For a list of all tycho related tutorials see Tycho Tutorials Overview

Source code for this tutorial is available on github as a single zip archive, as a Team Project Set or you can browse the files online.

Before we start signing stuff, we need a certificate. In our example, we will use a self-signed certificate, you will probably want to go for one from a certification authority.

Step 1: Creating a self signed certificate

There exist lots of tutorials out there, how to sign jar files with a self-signed certificate. I suggest you pick one and try to sign a jar file for test purposes. Here are the two commands needed to create the certificate, which can be executed in a shell:
$JAVA_HOME/bin/keytool -genkey -keyalg RSA -sigalg SHA1withRSA -keystore C:\userdata\workspaces\blog\com.codeandme.tycho.releng\sample.keystore -alias eve -dname "CN=Eve, OU=none, O=example, L=somewhere, ST=earth, C=ea, EMAILADDRESS=eve@example.com"

Enter keystore password: verystrong
Re-enter new password: verystrong
Enter key password for <eve>
        (RETURN if same as keystore password): secret
Re-enter new password: secret

$JAVA_HOME/bin/keytool -selfcert -keystore C:\userdata\workspaces\blog\com.codeandme.tycho.releng\sample.keystore -alias eve
(I always preferred Eve over Alice and Bob...)

The email address field seems to be necessary (thanks for the comment), see this message on stackoverflow

Step 2: Signing jar files with tycho

Signing will be done by the maven-jarsigner-plugin. Open the master pom located in com.codeandme.tycho.releng (see previous tutorials) and add following plugin section to it.
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jarsigner-plugin</artifactId>
    <version>1.2</version>
    <configuration>
     <keystore>${basedir}/../com.codeandme.tycho.releng/blog.keystore</keystore>
     <storepass>verystrong</storepass>
     <alias>eve</alias>
     <keypass>secret</keypass>
    </configuration>
    <executions>
     <execution>
      <id>sign</id>
      <goals>
       <goal>sign</goal>
      </goals>
     </execution>
    </executions>
   </plugin>
Set your passwords and the path to your keystore and run your maven build. Congratulations, you have signed your jars successfully.

Step 3: Create a code signing certificate for windows

Creating a self-signed certificate for your windows executable is not very useful unless you add your CA (we will create this in a second) to the trusted root certificates on the target machines. So this might be valid for a setup in a closed environment but not when your software is downloaded from the internet. In the latter case you need to buy a certificate from one of the big CAs (see this thread for some cheap ones).

Nevertheless for our test purposes such a certificate will do, so lets create one following this description on stackoverflow. We need to install Windows SDK, so download and run the installer. On the Install Options page select Windows Native Code Development/Tools, we do not need anything else for signing. After the installer is done you should find signtool.exe in C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin.

To create a code signing certificate, startup a command shell:
"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\makecert.exe" -r -pe -n "CN=Eve" -ss CA -sr CurrentUser -a sha256 -cy authority -sky signature -sv SampleCA.pvk SampleCA.cer
"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\makecert.exe" -pe -n "CN=Eve" -a sha256 -cy end -sky signature -ic SampleCA.cer -iv SampleCA.pvk -sv SampleSPC.pvk SampleSPC.cer
"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\pvk2pfx.exe" -pvk SampleCA.pvk -spc SampleCA.cer -pfx SampleCA.pfx
"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\signtool.exe" sign /v /f SampleCA.pfx /t http://timestamp.verisign.com/scripts/timstamp.dll Application.exe
  • Line 1 creates a root CA. You will be asked for a Subject Key twice. This is the key for your CA. Lets use "verystrong".
  • Line 2 creates a signing certificate using the root CA. The Subject Key is now the key for our signing certificate. So use a different one to that before (eg. "secret"). You will also be asked for an Issuer Signature, which refers to the Subject Key of step 1 ("verystrong").
  • Line 3 converts our certificate into pfx format. Again you need the Subject Key of step 1 ("verystrong").
  • Line 4 signs a fictional file Application.exe with our key.

To verify that signing worked you can open the Properties dialog of your executable and examine Digital Signatures.
    Step 4: Integrate signing in maven build

    For signing our executable we need to run the external signtool.exe by using the exec-maven-plugin. Open com.example.tycho.releng.product/pom.xml and add a new plugin section with following content:
       <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>1.2.1</version>
        <executions>
         <execution>
          <id>exec</id>
          <phase>package</phase>
          <goals>
           <goal>exec</goal>
          </goals>
         </execution>
        </executions>
        <configuration>
         <executable>C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\signtool.exe</executable>
         <arguments>
          <argument>sign</argument>
          <argument>/v</argument>
          <argument>/f</argument>
          <argument>C:\UserData\Workspaces\Blog\om.codeandme.tycho.releng\SampleCA.pfx</argument>
          <argument>/t</argument>
          <argument>http://timestamp.verisign.com/scripts/timstamp.dll</argument>
          <argument>${project.build.directory}\products\tycho.product\win32\win32\x86\eclipse.exe</argument>
         </arguments>
        </configuration>
       </plugin>
    
    Make sure you have no line breaks in your xml nodes!

    For MacOS this should work similar. To my knowledge you would just have to use another signing application.

    5 comments:

    1. Just a tip: The signed files with java 7 doesn't work on Indigo. You need to set: -keyalg RSA -sigalg SHA1withRSA

      ReplyDelete
    2. This is exactly what i was searching for, very precise article about this topic, really appreciate this.

      ReplyDelete
    3. Great article ... for maven newbies like me, check out how to encrypt the keypass so you don't store it in clear text when you checkin your source http://maven.apache.org/guides/mini/guide-encryption.html

      ReplyDelete