Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

Two separate discussions have very recently opened my eyes to an issue I had not considered – how to confirm the Open Source binary one uses is based on the published source code.

There is a large discussion thread on cryptography-randombit based on Zooko Wilcox-O'Hearn's, founder and CEO of LeastAuthority.com, open letter to Phil Zimmermann and Jon Callas, two of the principals behind Silent Circle, the company that ran Silent Mail which touched on the subject. Additionally, a Dr. Dobbs article published today entitled Putting Absolutely Everything in Version Control touched on it as well.

The issue of concern for this question is ability to recompile Open Source code and get the same results as the published binary. In other words, if you recreate the same binary and hash it from source code it is unlikely to be identical due to differences in tool chains and some randomizations in compilers themselves.

The Dr. Dobbs article suggests putting even the tool chain under version control for reasons of reproducibility. Jon Callas points out that in many cases it may be impossible to redistribute the tool chain for various reasons including licensing restrictions. Unless you are compiling the code yourself you are adding a trust step to your assumption set as the binary cannot be even recreated by others with the same results.

I now understand that this is an understandably accepted risk. My question is are there other discussions or indicatives relative to making source code byte for byte reproducible when compiled thus eliminating the need to trust the provider of even Open Source binaries? As referenced in Jon Callas’ discussion Ken Thompson showed “You can't trust code that you did not totally create yourself.” What are the security implications thoughts on this subject?

share|improve this question
add comment

3 Answers

up vote 4 down vote accepted

If you can recompile the source code and have your own binary, then maybe you won't be able to get the exact same binary as the one that is distributed; but why would it matter ? At that point, you have your own binary, which necessarily matches the source code (assuming your compiler is not itself malicious): you can just ditch the binary package, and use your own binary.

In other words, situations where you would be able to verify the compilation output are situations where you can compile yourself, making the verification a moot point.

There are package distribution frameworks out there, which rely on source code distribution and local compilation instead of binary packages; e.g. pkgsrc (the native system for NetBSD) or MacPorts (for MacOS X machines). However, they don't do that for trust or security, but because distribution of binary packages involves build systems somewhere, and these are not free; also, one point of pkgsrc is to provide easy management of local compilation options.

The famous Thompson essay highlights the idea that even making your own compilation is not enough. Taken to the extreme, you should write your own code, but also your own compiler, and run that on hardware which you designed and engraved yourself: you cannot trust the machine unless you started with a bucket of sand (for silicon, the main component of semiconductors). This is, of course, quite impractical. Therefore, we need the second best thing, and that second best is a paradigm shift: replace trust with violence.

What we do is that binary packages are signed. The package installer verifies the signature before installing it, and rejects packages which do not come from "trusted sources". The same concept applies to Java applets, which can be granted extra permissions (and, indeed, permission to do whatever they want with your computer) provided that they are signed. Note that this is indeed a signature, not just an authentication; it is not sufficient (nor indeed necessary) that the package was downloaded from a "trusted repository" through HTTPS. Such a download would give you quite some guarantee that the package comes from whom you believe, and has not been modified in transit. But you want more: you want a proof. You want a signature because IF the package turns out to be clock-full of malware, THEN you can use the signature to demonstrate that the package provider was an accomplice, at least "by negligence". From signatures comes responsibility, and responsibility works on fear. Fear of litigation from abused customers. Fear of retaliation from law enforcement agencies. Ultimately, fear of violence.

share|improve this answer
You had me at melting the sand. –  zedman9991 Sep 4 '13 at 0:37
How can you guarantee the sand has not been compromised? –  Terry Chia Sep 4 '13 at 1:05
add comment

I like determinism.

A compiler or any software tool is really a devious mathematical transform. It takes s (source code) puts it in a function C() and produces a binary output b.

b = C(s) every time! otherwise determinism fails and we all go mad.

So the theory goes, as long as we start with the same s, and the same C(), we will always produce the same b.

And this is good because we can perform a hash of b or H(b) and get a relatively short value which we can compare to someone else's H(b) to make sure that are binary is the one we expect.

And then change happens: s changes to s', C() changes to C'(). Oh no!

Because C(s) = b1 and C'(s) = b2 and C(s')= b3 and C'(s') = b4

and of course no two of H(b1), H(b2), H(b3), or H(b4) with ever match.

And the problem is that as the components (tool chain, environment, configuration, OS, etc) that are required to produce binary b get more numerous and interdependent it becomes harder and harder to reproduce the same b.

Wait, what if we didn't need the exact same b?

We then we are dealing with b and b' and the difference between them.

All you need to to find the difference between a reference binary b and your generated binary b' and look at what the difference means. If the source for b and b' is s then that means we are dealing with C() and C'. And thus we can correlate the difference between C() and C'() to the difference between b and b'. So even if we can not exactly reproduce b we can gain some confidence in b' by leaning what difference is cause by using C'() instead of C().

share|improve this answer
Good points. I guess the technique for determining that the source for b and b' is indeed the same is the sticky point since the compilers are in the hands of others. –  zedman9991 Sep 4 '13 at 12:14
add comment

One of the fundamental things that you are trusting in a binary is the place you got it from. If sourceforge or download.com or whoever says its free of viruses and thats good enough for you, go for it. You're taking their word on it.

IF you don't want to trust a binary then the only other real answer is to compile from source code. Either to something like java bytecode that you can run, or a jar, OR all the way to a binary.

If you compile your own binary, yes you might end up with something that is the same as the standard binary (meaning that EVERYTHING is the SAME, a bit for bit match) Great! you happened to be running the same hardware, compiling for the same processors, nobody had accidentally left an extra line break in your copy of the code.... whether it matches or not, at that point you're trusting the code that you just had (the ability at least) to read. If you don't know C++ and you don't trust other people who have vetted the code, then tough. Learn C++ and vet it yourself.

This all boils down to you can't verify a binary unless everything matches EXACTLY. You can always verify the open source code for something though. Whether you take the time or whether you trust the analysis that some one out there has presumably done is your choice.

share|improve this answer
add comment

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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