20

When someone downloads the Monero source tree from github, there is a possible risk that this is not what the developers created. This could be MITM attacks, whether between developers and github or between github and the downloader. It could be github being compromised or itself mounting an attack.

As seen in https://github.com/monero-project/bitmonero/commits/master, the Monero developers use GPG to sign commits.

  1. Does relying on github's "Verified" label carry any risk ?
  2. How can I use these signatures to verify locally my source tree is genuine ?
  • 2
    Check the checksum. Perhaps the checksum can be stored in a chain for distribution to the public assuming sophisticated attackers exist and would want to mess with you to the Nth degree. Realistically a sha512 checksum checkup on monero source should suffice. – JohnHanks Jul 27 '16 at 15:28
  • 2
    This is done for the binary releases. I think that storing either commit hashes or detached commit signatures on the blockchain every time something is pushed is really complicated though. Not to mention it forces everyone to have a current enough tree to be able to parse the blockchain (ie, a newcomer must first build monero, then sync the chain, then look at the last commit on the chain). You could use the bitcoin chain I suppose, but it only gets rid of the chicken and egg bit. – user36303 Jul 27 '16 at 15:58
21

Signed git commits allow a user to verify the source was signed by one of the contributors. In order for this to work, however, several steps have to be taken:

The user must have git and GPG installed. While git will typically be installed already if the user wants to use github, GPG may not be. Make sure to install it from your distribution's packages, or from its source, and verify signatures and/or hashes. Downloading a trojan GPG is not a great way to start.

The user must then import the public keys that will be trusted. Most of those public keys are in the Monero git tree (in the utils/gpg_keys directory). Simplest is to import them all, though some of the contributors are not active any more:

gpg --import utils/gpg_keys/*.asc

GPG now knows those keys, and will use them when verifying a signature.

To verify a commit, or a tag, git will automatically use GPG if told to:

For a commit (here, the last one):

git show --show-signature

For a tag (here, the tag for version 0.9.4):

git tag -v v0.9.4

When you download the tree, or update it, you'll want the first command. It will check the signature for the latest commit. It is implicit that, if you trust the person which signed that last commit, you trust that person to have built upon a tree that was also signed by someone they trusted, so you do not have to check every single commit - there'd be thousands.

If a commit is not signed, it will not say anything about GPG signatures, since there is nothing to check. If a commit is not signed, alarm bells should ring. Most of the Monero maintainers sign their commits, and, for those who don't, fluffypony signs the merge, so you should always see a signed commit by fluffypony as the latest commit. This may change in the future, but the latest commit should always be signed.

If a commit is signed, you will see a couple lines about the GPG signature. One line tells you a signature is present, and tells you the key id that made the signature. You also get an email address, but this is easy to forge, and meant just as an aid. You will want to double check the key which made the signature is indeed one you want to trust: one of the ones you imported in the step above. For instance, fluffypony's current signature id is 1CCD4FCD. Always good practice to verify several sources: when importing signatures, you should see that same key id. If not, then ask questions.

The second line tells you whether the signature was good. A good signature is one that corresponds to the commit being signed. A bad signature is one that doesn't (i.e., either the signature, or the commit being signed, was altered after the fact. Or both). If you do not get a "Good signature", then something is wrong.

Last, you might get a warning that the signature was not made by a trusted signature. This can be ignored, as you did not tell GPG to ultimately trust those signatures. You could do so if you wished, but that goes into editing key properties, so I will leave it at that. Suffice to say that the trust you should afford is whether they signature signing a commit is one of the ones from the Monero contributors, based on matching key ids (note that key ids are a bit short, so it's theoretically possible that a key is forged to get the same key id. I'm not sure how practically feasible this is at this time).

So now you hopefully have it all checked out and your Monero tree shows as being properly signed by the right key. :)

It is important to realize that if those signatures are checked, it is irrelevant to consider where the tree was obtained from. As long as the signature checks out, you can be sure that wherever it was, nobody could have tampered with it, or the signature would not check out. This makes it safe to pull a tree from a seedy place (save any exploits trying to pwn git or GPG themselves by crafted trees, etc, but this is becoming way more unlikely).

This takes care of the second question. With this knowledge, we can now answer the first:

Relying on GitHub's "Verified" label is better than not relying on anything, but worse than checking signatures yourself. Why? Because you are trusting a third party to check things for you and not lie to you, as well as opening yourself to MITM attacks, or GitHub being compromised. After all, what would prevent GitHub or someone compromising GitHub from placing a "Verified" label on the page? Nothing, but checking signatures yourself will uncover the treachery.

Last point: if you're going to pull and build often, there is a script that helps with this, posted by moneromooo, a Monero contributor: https://bitcointalk.org/index.php?topic=583449.msg15315904#msg15315904 This points to a signature, which you can check with the instructions supplied. Since it's signed with moneromooo's signature, which is in the Monero tree, it also can come from any random site, as long as you check the signature to be from that same key. It's a good exercise :) This script is meant to replace running make. It checks signatures, then runs make if they check out (and complains loudly without running make if the signatures do not check out). This ensures that, if you use this script to build, you can't forget to check signatures and unwittingly run source that was tampered with. Why is this not in the Monero tree? See that post for details.

So the morale of the story is, always verify signatures!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.