A Web 3.0 Approach to Distributing Signed Software
TL;DR — distributing signed software is hard. Check out our open source system that makes it easy at valist.io and signup for the beta for awesome pre-launch perks!
The Current State
Digitally signed software is a requirement for verifying the integrity of the applications you are running. Whether it’s a web browser, or firmware inside of your pacemaker, installing the correct software (i.e., not malware) is crucial.
It’s just as important to keep your software up-to-date, since 0-days (undiscovered vulnerabilities, often exploited in the wild) are constantly being discovered.
If up-to-date, digitally signed software is so important, why is it so hard to implement correctly?
Even once you sign your software, how do you distribute it securely?
These are things that many developers end up implementing themselves over and over again, in slightly different ways, and yet the process is largely the same regardless of the application.
If you use a Mac, you’ve likely ran into this popup, or something similar:
Despite how annoying this popup is, Apple is great at enforcing these requirements. This has no doubt saved countless victims from installing unofficial software. However, they have a stronghold — in order for a developer to prevent this popup, they need to sign the binary with an Apple Developer account, which costs money. They also limit number of developer certificates that can be generated. Furthermore, with the release of macOS 11 Big Sur, all binaries on the system have to be digitally signed before they can run, so this trend is unlikely to go away.
Desktop software on Macs is one thing, and certainly hits close to home for many, but let’s not forget critical infrastructure like our power grids, industrial control systems, medical devices, routers, vehicles, satellites, and our increasingly smart homes. It is extremely important that these systems are built with integrity and are running the correct, and latest, software.
So how can we make this process more democratized? We need to build easy to use systems that enable developers to release signed software to the masses, or into critical infrastructure.
The biggest hurdle to digitally signed software in many enterprise contexts is the Public Key Infrastructure, or PKI, which is required to generate certificates for organizations and developers to use.
These are typically run by Certificate Authorities, or CAs. CAs manage “root” certificates that they keep offline and store with high security. This allows them to generate “intermediate” certificates that they use to generate the “leaf” certificates your browser ultimately interprets. All of this is called a “Chain of Trust” — and it just so happens to be the fundamental basis of a secure Internet.
For example, if you click on the lock in your address bar while you’re reading this on desktop, you can view Medium.com’s leaf certificate, and verify it was issued to them by a popular CA, DigiCert:
The reason that your browser trusts Medium’s certificate is because it already trusts DigiCert. Where does this implied trust in DigiCert come from in the first place?
On your computer or phone’s operating system, you have a pre-installed set of Root CA certificates that are used to verify certificates that ultimately come from these authorities, regardless of how far down the “chain” of trust they are.
The Root CA certificates you have pre-installed are managed by the vendor of your operating system — meaning Apple, Microsoft, Google, or your Linux distro must keep these updated when they are hacked, renewed, or otherwise deemed untrustworthy.
On macOS, you can check out the Root CAs your computer trusts by opening the Keychain Access application, and clicking on System Roots:
DigiCert’s root certificates are highlighted in the image above. Since these are installed, any valid certificate that originated from this root of trust are inherently trusted.
Whenever you as a developer, or an organization, need an SSL (TLS these days) certificate to enable HTTPS on your website or server, you generally have two options in order to get the “green lock” and avoid browsers blocking your service:
- Purchase a certificate from a CA that can last for as many years as needed
- Use Let’s Encrypt, an (incredible) free service, and renew every 3 months
These are valid and relatively easy options when running a simple webserver.
However, the model begins to break down a bit when using these certificates to sign applications. Developers and organizations need to purchase a long-living certificate from a “trusted” authority, and free Let’s Encrypt certs are out of the picture since they expire far too quickly and will likely cause applications to become inaccessible. Once a cert is acquired, it must be managed very securely, and developer access control should be limited.
Because of these reasons, among others, many developers choose to use PGP keys to sign applications. With PGP, a developer can generate their own public/private keypair and use their private key to sign. They associate their public key with their email address on keyservers that institutions like MIT run like https://pgp.mit.edu/. This allows anyone to verify the signature of the developer by checking their public key against the signature. You can check out some interesting PGP stats here: https://sks-keyservers.net/status/key_development.php
This is entirely self-service in the sense that a developer or organization can create a public/private keypair, publish their public key on a popular keyserver like MIT’s, and on their own website, and sign away.
This is a step in the right direction, and works in many cases, but it still leaves the infrastructure and security policies surrounding proper key management and access control as a burden on the developer and organizations they work with. PGP also still suffers from many UX problems after all these years — it’s a pain to work with in most cases.
If an organization wants to associate a public keys with developers that have different permissions to publish software, they have to build the access control themselves. They also have to implement measures for when a developer loses a key, or worse, has their key compromised.
This often leads to several…less-than-ideal situations:
- The keys are all controlled by one or two developers
- The keys are difficult to rotate (renew) without causing issues
- The keys are often generated with less secure defaults
- The keys are backed up insecurely or not backed up at all
On top of all this, once the application is signed, the binary still needs to be distributed! Often the organization will publish the application on their website and various distribution channels, along with a PGP public key you can use to verify the integrity (another UX pain).
Again, all of this infrastructure is up to the developer and the organization. This doesn’t exactly resonate with the age-old adage of “Don’t Repeat Yourself” that every developer has been ingrained with.
A Way Forward
Can we build a system that solves for the problems of trust, proper key management, access control, and distribution all at once?
Of course! Thanks to the recent advances in decentralized technology, we are able to eliminate these roots of trust, and many of the security and usability pitfalls that come with them.
To do this, we can use a few robust tools that have emerged from Web3: Ethereum, IPFS, and Filecoin.
Ethereum is a globally distributed compute platform that secures over $60+ billion in assets without a centralized authority.
All transactions on the network have their signatures checked prior to execution, and all computation is verified by the network.
Strong keypairs (ECC-based keys) are used to interact with Ethereum networks, and we can use these same keys to sign software and authorize new releases.
We can use Ethereum smart contracts as a source of truth for several key functions:
- An always up-to-date, trusted record of every software release for a given repository
- Role Based Access Control for developers and organizations
- The locations and hashes of where software releases are stored
When it comes to storing our signed software releases, we can use IPFS — the InterPlanetary File System.
IPFS is a peer-to-peer filesystem. You can think of it like a filesystem with a built-in CDN.
IPFS uses cryptographic hashes to route content, rather than regular URLs that are based on a location that ultimately maps to an IP address and depends on a server response.
A URL in IPFS looks something like this instead:
In this case, IPFS is fetching a file with a particular hash. Once it finds it on the network, it can download a cryptographically verified copy of that file and help serve it to others later.
It also provides natural data de-duplication, since it understands that regardless of the name of the file, the hash will be the same, and only stores one unique copy per IPFS node/server.
IPFS works fantastically now as-is, and Filecoin is an incentivized version that allows for long-term storage of files and the ability to set a rate you’re willing to pay for storage. As of the writing of this article, it is currently 3.75x cheaper than Amazon S3:
These rates are subject to change, and IPFS will continue to be used for “hot” storage, but Filecoin seeks to set a standard for long-term storage.
Filecoin’s mission is to be a “decentralized storage network designed to store humanity’s most important information” which is a great use-case for critical firmware.
By putting all of these systems together, we can create a model that looks like this:
A smart contract checks whether the developer is authorized, and if they are, it stores the latest IPFS and/or Filecoin content-address for that release.
By subscribing to the Events of a repo’s contract, we can instantly be aware of any new releases and other events associated with it.
Organizations can easily manage access control and set roles for developers that will be automatically enforced throughout the network.
You can also use it as an internal caching layer for any of your software packages. All of your Linux distro’s packages, NPM packages, Python packages, Rust, C++, Go — you name it — can be distributed through this system.
Remember the “left-pad” incident? We can prevent that from happening ever again. Check out this article if you are lucky enough to have not heard of it: www.qz.com
Valist.io is a system built exactly for this purpose: to make it incredibly simple for any developer to sign, publish, and distribute software and firmware without concern of infrastructure, security, or PKI related pain.
We are building on the foundations of Web3 technologies, but with a keen focus on backwards compatibility and integration with traditional HTTP-based and non-p2p systems.
We currently support arbitrary binaries, NPM packages, Python packages, and Docker images, with support for many more registries coming soon.
We are also building support for “Multi-Factor Software Releases” where you can require multiple developers or admins to sign-off on new critical releases. For example, “in order to publish new firmware for a hardware wallet, 7 out of 10 developers must sign off on the release,” or any other configuration of authorization steps.
This is especially important for open source projects, as it enables the community to verify that builds are correct and publish releases together without trusting individual maintainers.
Valist will allow you to:
- Securely distribute any software or firmware
- Enforce Multi-Factor software releases
- Manage access control for developers and organizations
- Create over-the-air update systems easily
- Cache all of your software packages, speeding up build times and increasing infrastructure integrity
- Allow developers to use HSMs like YubiKeys, hardware wallets, and mobile devices to sign and authorize software releases
If you find this interesting, click the link below or visit valist.io and sign up for our beta for some awesome pre-launch perks. We’re building a community of security experts, software engineers, blockchain engineers, and technologists that are passionate about building a better, more robust world for the future.
Check out our Github at: https://github.com/valist-io/valist
We’d love to connect and hear your thoughts and feedback! If you enjoyed this article, please share it with your friends and co-workers.
Follow us here on Medium, or on Twitter at https://twitter.com/Valist_io for more content relating to security, crypto, and decentralized technologies! You can also email me personally anytime at email@example.com or firstname.lastname@example.org
Have a great rest of your day/evening, and thank you for reading!