123456789_123456789_123456789_123456789_123456789_

RubyInstaller Windows executables are signed by a Microsoft trusted certificate. It is issued for "Open Source Developer, Lars Kanis". The certificate authority used is Certum. They provide a set of card reader and cryptographic smart card for 85€ and an annually certificate for €30. These are reduced prices for Open Source Developers. The smart card stores the private key and the corresponding certificate can be downloaded after issuing. Issuing the certificate and signing the RubyInstaller executables is currently done on Ubuntu, not on Windows.

Key generation and certificate issuance

The activation process of the ordered certificate is done with the help of a java applet that acts as a proxy from the Certum web application to the smard card. It requires OpenJDK-8, PCSC and the smartcard reader driver to work properly. So on Ubuntu the following packages are necessary. Since icedtea-netx defaults to OpenJDK-17, the java default version has to be changed:

sudo apt install openjdk-8-jdk icedtea-netx libpcsclite-dev pcscd libacsccid1
sudo rm /usr/lib/jvm/default-java
sudo ln -sf /usr/lib/jvm/java-8-openjdk-amd64 /usr/lib/jvm/default-java

Then the java applet can be started on the Certum certificate activation web page or with the downloaded applet manifest like so:

javaws ~/Downloads/CertumCryptoAgent_en.jnlp 

If everything works well, the web application can generate a RSA-4096 bit key on the smart card and start the certificate issuing process.

Signing the executables

The RubyInstaller executables are currently signed in the rubyinstaller.org-website project. It makes use of https://github.com/larskanis/osslsigncode and the PKCS#11 library file provided by Certum. After installing necessary dependencies as described in the project README and make install, the command looks like so:

osslsigncode sign \
  -verbose \
  -pkcs11engine /usr/lib/x86_64-linux-gnu/engines-3/libpkcs11.so \
  -pkcs11module /opt/proCertumCardManager/sc30pkcs11-3.0.6.68-MS.so \
  -certs <my-certificate>.pem \
  -key <key ID on the smart card> \
  -pass <smart card password> \
  -h sha256 \
  -t http://time.certum.pl/ \
  -in <to-be-signed>.exe \
  -out <signed-file>.exe

The PKCS#11 library sc30pkcs11-3.0.6.68-MS.so is not available as a separate download, but it's part of the proCertumCardManager. It is free to download and installs into /opt/proCertumCardManager. It also needs the PCSC packages and reader driver of the apt install command above. The full signing command is here.

The certificate pem file can be downloaded from the Certum web site after issuance and can inspected by the openssl command:

$ openssl x509 -in <my-certificate>.pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            3a:de:93:0a:dc:9e:8b:c4:de:42:57:b2:2c:a2:d3:f9
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = PL, O = Asseco Data Systems S.A., CN = Certum Code Signing 2021 CA
        Validity
            Not Before: Oct 23 07:38:08 2023 GMT
            Not After : Oct 22 07:38:07 2024 GMT
        Subject: C = DE, ST = Thuringia, L = Greiz, O = Open Source Developer, CN = "Open Source Developer, Lars Kanis", emailAddress = lars@greiz-reinsdorf.de
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
                Modulus:
                    00:96:28:94:b2:eb:20:10:c0:49:4c:6f:2e:5b:4a:
                    [...]
                    45:40:70:23:c3:64:51:b5:00:a2:0b:53:fb:bd:67:
                    c0:bf:e5

There's also a small helper in the Rakefile, which prints the Key IDs on the smart card and the modulus. This is helpful to select the correct key corresponding to the certificate to be used. The output looks like so:

$ rake signtool:list-keys  # List keys from PKCS11 signature stick
========== Key 0 ==========
ID: ee96a6ada894a9ab64e47b7fec23a985c6d68d5b
Modulus: 9b96a45f661127ee...c7fa3bbdca53b591
========== Key 1 ==========
ID: 948d4a78793978fbbc8f77e43c1cd30251bfb137
Modulus: e7c40d3ff3117da7...2181fdc7dff33075
========== Key 2 ==========
ID: b31eefae6f8353837329fdf37d40664a1ea99937
Modulus: 928de2c7fe41eadf...3b4e3406168df055
========== Key 3 ==========
ID: 739d150ea2185d25c2f7bcd34cc8b733126686cb
Modulus: 962894b2eb2010c0...0b53fbbd67c0bfe5

You see "Key 3" is the right key for the above certificate, so that its ID has to be used for the osslsigncode command. In any case osslsigncode verify should be used to check the signature afterwards, as done in the Rakefile.