Skip to content

Double Signature solution

Oz DiGennaro edited this page Sep 26, 2018 · 7 revisions

In contrast to other proposed solutions Double Signature (DS) does not jump the gun of strong encryption right from the beginning of implementation. There is a strong belief CA is an overkill for the problem. See DS comments thread to discuss its reasoning. DS method shifts focus from mandate trusted certificates in ruby community to a help to Rubygems.org identifying attempts of changing gem after public version was released. The door to build full scale identity authentication is still open with DS and can be done at second phase if practical demand exists.

DS solution based on following principals:

  • gem signature service is separate from Rubygems.org (REPO) and handled by Trust Centre (TC) hosts;
  • TC host must not have any public user accounts, just an admin;
  • chance one TC is hacked low but realistic - do not trust to any TC alone;
  • risk of two independent TCs are hacked at same time is practically negligible for most users;
  • gem installer can validate gem signatures from two, three and more TCs;
  • gem release can be made to the public one time only. If any critical error or compromise is found gem then release can be announced as unavailable;
  • once release been announced unavailable it is final state. It can not be revert back as available. Instead a new release with next version number can be made to the public.
  • TC memorizes gem file size and one or many signatures (SHA512, MD5 etc)
  • TC has to support https for signature publishing (https://tc1.rubygems.org/signatures/hike/versions/1.2.1/SHA512)

To implement DS.

  • Rubygems.org is required to support a request for recent gem releases – an announcement. Trivial change.
  • Implement TC as crawler daemon that generates signatures and static web server to display gem signatures to the public. Quite simple task if at first phase something simple like SHA512 is used as signature.
  • Change gem installer binary that downloads signatures from TCs and validates gem before any installation actions. Also same binary may be used to check gem withdrawal requests. The most time consuming part. However if we stick just to SHA512 signature it looks like doable task in not so long time.

Addressed Goals and Constrains:

  • Know when a gem on the rubygems server has changed since upload
  • Allow for gem to be revoked when it’s malicious
  • Patch rubygems binary to warn on insecure downloads
  • Rubygems is a project run by volunteers so up-front and maintenance costs should be considered
  • Limit complexity on gem user side
  • No additional complexity on gem developer side
  • Can be used with all old existing gems.

How it works

Publishing new gem release

  1. gem owner publishes new release of the gem in REPO
  2. REPO adds the release to announce
  3. At scheduled time TC reads announce on REPO
  4. TC downloads the release and generates signature

Installation of gem - successful

  1. gem installer reads TCs addresses (at least two) from local configuration
  2. gem installer downloads gem package from REPO and signatures from all TC specified
  3. gem installer validates gem package is not tampered by checking all signatures
  4. gem installer proceeds with installation of gem package

Installation of gem - unsuccessful

  1. gem installer reads TCs addresses (at least two) from local configuration
  2. gem installer downloads gem package from REPO and signatures from all TC specified
  3. gem installer identifies gem package is tampered by mismatch with at least one signature
  4. gem installer notifies local user and sends report to REPO support

Note, in case missing signature gem package is not tampered with but installation can not continue.
Bonus. The most popular packages will be under constant monitoring by end users installations.

Installation of gem – when extra care required

  1. Company buys validation service from third party.
  2. Third party TC does not sign released gem automatically. TC daemon can be same code-base as public.
  3. Third party does code review and possible contacts gem author (here you go with CA or anything)
  4. Once code authenticity is confirmed, third party TC signs public release.

Bonus. TC service can be an alternative to those companies who just need an insurance in gem code instead of full burden to validate by itself in private gem repositories.

Withdrawal of compromised gem

  1. REPO support investigates facts in report received from gem installer run by user. (comparing signatures on public TCs)
  2. REPO support marks compromised gem as unavailable for download
  3. REPO announces the gem release as unavailable
  4. TC reads announce and replace gem release signature by “withdrawn”
  5. As part of maintenance gem installer run with “check” command that reads signatures for all locally-installed gems. In case “withdrawn” is found notifies local user.
  6. Local user confirms removal for “withdrawn” gem.

Pros & Cons

pro

  • Relatively simple implementation. First phase can be done in short time. Less coding effort and testing required from volunteers.
  • Gradual approach to increase complexity and level of trust. Allows constant improvement by try /error method with minimal impact to general ruby community users.
  • Flexible, non invasive architecture. Any one can sponsor a big project for TC at level of implementation he wants.

con

  • Instead of true authentication of gem code, first phase offers compromise of insurance (monitoring mechanism) that validates no one tampered with the public releases.

Discussions


DS solution comments
CA is “overkill” for gem authentication
List of realistic attack scenarios
Separate gem signing from gems themselves
PGP/GPG as a Ruby gem dependency is a non-starter