Distribute open-source software: the right and verifiable way

Orkun Kulce
Starname Blog

--

I downloaded the code and built it. But uhhh.... How do I verify that the code is same as yours and not manipulated somehow?

Let’s begin the article with a story: King of the CryptoLand, the land where you use Bitcoin to buy haystack and use Dogecoin to pay your taxes, wants to organize a feast where he can show off the ingredients and spices which he received as war booty from his latest campaigns. He orders his servants to hand over the ingredients to the royal cooks. But the problem is that the spicery is extremely valuable. How could the king be sure that the same ingredients are used to cook the feast and that the cooks did not replace the ingredients with cheaper inferior ones?

Distributing open-source software carries the same problem. How to verify the downloaded version is using the same dependencies and binaries? Any malicious actor could inject his own code on the transmission.

Solving CryptoLand king’s feast problem with today’s technology is possible. You could run some tests on the meal and verify that the same ingredients are used in the cooking. But how to achieve this with information that could be copied and manipulated million times with just a click?

Developers of Bitcoin tackled this problem while developing the software and on the fly, they developed Gitian Build.

Gitian is a secure source control oriented software distribution method. This means you can download trusted binaries that are verified by multiple builders.

Gitian uses a deterministic build process to allow multiple builders create identical binaries. This allows multiple parties to sign the resulting binaries, guaranteeing that the binaries and toolchain were not tampered with and that the same source was used. It removes the build and distribution process as a single point of failure.

At IOV we use the same build process that is used in Bitcoin as well as in Cosmos.

Let’s explain how to build IOV Name Service Daemon(formerly known as BNSD) and Tendermint.

First, start withBNSD :

If you are using macOS, make sure you run apt-cacher:

Generate the PGP key if you do not have one. You will be prompted to enter a password for your key. You will be using this password every time you encrypt, decrypt, and sign. Make sure you choose securely and easily remembered password(not 12345 please). I suggest diceware for your important passwords: https://en.wikipedia.org/wiki/Diceware

Gitian runs verification with already existing public keys during building. I recommend that you import our keys before the build. Here you can download and import mine from https://keys.openpgp.org/vks/v1/by-fingerprint/5B9D656490263932B97977DDC30516DE62474BF1

Now we are all set for signing the build:

user@example.com should be replaced by your PGP mail. testname@mail.com in this example.

The build process will take some time, so be patient. During the build, you will be asked to enter your PGP key to initiate the signing process.

You will see a PGP signature verification output at the end of the build:

Beware if you did not import our PGP public keys you will see BAD SIGNATURE instead of OK .

After the build process is done, abnsd.sigs folder which contains signatures will be generated:

If you want to add your signature to bnsd.sigs repo as well, fork the weave repo on GitHub, then checkout:

git checkout -b <build-version>-linux-<pgp-public-key-mail>

and push to upstream:

git push --set-upstream fork <build-version>-linux-<pgp-public-key-mail>

then create a PR to merge to the weave repo.

We have signed weave repo (meaning BNSD ). Signing tendermint repo https://github.com/iov-one/tendermint-build is similar to signing bnsd. You can follow an almost identical script on README.md file.

Let’s take security one step further. PGP keys are vulnerable to the same risk vectors, mainly: hijacking. If a malicious actor gets hold of your keys, they can sign anything on your behalf. We can apply the same approach that is introduced by hardware wallets. Instead of keeping our PGP private keys on local, we can keep the keys in a SmartCard such as YubiKey. All PGP related computation could be done on a SmartCard without being exposed outside.

We will be creating a master key for certification and subkeys that are generated by the master certification key. For more info on this PGP key model please refer to https://blog.eleven-labs.com/en/openpgp-almost-perfect-key-pair-part-1/

I recommend using a clean live USB bootable ubuntu while following the steps mentioned below. If we want to use YubiKey for securing keys it means that we value software security so why not take one more step using a live distro?

First, create a temporary directory for GPG generation:

Second, generate a GPG key with individual subkeys for signing, encrypting, and authentication:

Set your email as shown above.

Then verify that your PGP key is generated successfully:

Export the generated key id to an environment variable:

export KEYID=0xFF3E7D88647EBCDB 

Save a copy of the key:

gpg --armor --export-secret-keys $KEYID > $GNUPGHOME/mastersub.keygpg --armor --export-secret-subkeys $KEYID > $GNUPGHOME/sub.key

I recommend you to save these keys to a secure location such as LUKS-encrypted USB drive and store it in a safe place at your home.

We have generated our keys, now we need to transfer them to Smart Card.

Plug in the Smart Card (YubiKey in our case), and check that Smart Card is working:

Change the device pin for more security.

Transfering keys:

Toggle to key 1 by typing key 1 :

Repeat the process for the other keys too by toggling key 2 and key 3 .

Save the keys to the card:

Verify keys are saved:

You will notice ssb has > different from previous examples. > means the key is on the card.

Verify you saved the keys to the encrypted USB, then delete all the keys from local either by rm $GNUPGHOME or by rebooting. Remember if you lose your smart card you can always retrieve your keys from the stored USB. You can always create new keys from your master key.

Publish your key to a keyserver so people can find you

gpg --keyserver keyserver.ubuntu.com --send-keys $KEYID

Now you know how to distribute your code securely, and also how to secure your identity.

Happy coding!

--

--

Orkun Kulce
Starname Blog

Software crafter. Bedroom electronic music producer.