views:

296

answers:

7

For security reasons, it is desirable to check the integrity of code before execution, avoiding tampered software by an attacker. So, my question is

How to sign executable code and run only trusted software under Linux?

I have read the work of van Doom et al., Design and implementation of signed executables for Linux, and the IBM's TLC (Trusted Linux Client) by Safford & Zohar. TLC uses TPM controller, what is nice, but the paper is from 2005 and I was unable to find current alternatives.

Do you know another options?

UPDATE: And about other OS's? OpenSolaris? BSD family?

A: 

I feel reasonably confident in asserting that there's no such thing. SElinux doesn't do this. Linux distribution stop at signing patch bundles.

bmargulies
The OP asked a specific question: could he do code signing in the way that Windows does it? I stand by my answer. The fact that there are other mechanisms that address the underlying problem is also interesting, but the there is still a simple answer to the question.
bmargulies
A: 

The current way to do this is just with an md5 sum of the tar file. This is the way Apache does it.

David W
Voted down - this is not a proper solution. Anyone can generate md5 for a file, but only one person can sign it with the proper key. md5 summing the source relies on your trust in the md5sum checker, tar itself, the compiler and the loader.
viraptor
If this is the way that the Apache foundation solves this problem, I don't see how it can be an improper solution. I did not say explicitly that the md5 needed to be published on your web site and better if your website is certified. It's clearly not the best solution, or as good as the ones voted up. An answer voted up has the same comment:DM>> Instead, this kind of software relies more on generating signatures and/or secure hashes of the source packages.
David W
+4  A: 

The GNU/Linux/FOSS model actually encourages tampering -- of a sort. Users and distro-makers must be free to modify (tamper with) the software to suit their needs. Even just recompiling the software (without changing any source code) for customization is something that is done quite often, but would break binary code-signing. As a result, the binary code-signing model isn't particularly well suited to GNU/Linux/FOSS.

Instead, this kind of software relies more on generating signatures and/or secure hashes of the source packages. In combination with a reliable and trusted package distribution model, this can be made just as secure (if not more so, vis-à-vis transparency into the source code) as binary code-signing.

Dan Moulding
Thanks for your response. I am not sure if both things are in the same category. During "install time", you are pretty right: a trusted package system is required. But I'm worried about "loading time", ie, the software was tampered after install (it is tampered if compared against the trusted distribution signed software). So, I think we are talking about complementary issues. For example, TLC uses a sealed kernel master key to ensure, at boot time, the kernel to be loaded is a trusted one. It employs a TPM chip, so hardware is helping us to ensure the kernel is fine.
TH
What you can do quite well though is verifying the binaries in some closed domain (your company for example). If you have the same setup on 100+ hosts, then you can just use the verification to check that noone changed the data on the disk. It's like a hardware-supported Tripwire.
viraptor
+1, Best answer
Tim Post
@TH: Sorry, I guess I misunderstood your question. I confess that I only quickly skimmed the TLC paper (it was long and I don't have time to read it now). On it's face, however, I'm not sure a "load-time" integrity system provides *significantly* better security than traditional Unix security measures provide. I think installation and distribution of covert malicious code is the far more insidious problem. After all, in order to *load* bad code it's got to first be *installed* on the system somewhere. More layers of security are usually better, of course. The question is: is it worth the cost?
Dan Moulding
+1  A: 

Take a look at Medusa DS9. I played with it a long (long) time ago, but if I remember correctly, you could register specific binaries and any modification was not allowed at the kernel level. Of course, it can be overridden with local access to the machine, but it was not really easy. There's a smart daemon, called constable, checking everything that happens on the machine and if something out of the ordinary occurs, it start screaming.

Stefano Borini
+1  A: 

Have a look at this: http://linux-ima.sourceforge.net/

It's not signing yet, but it still enables verification.

viraptor
Thanks. IMA looks an "alive" initiative (TLC and DigSig look pretty "dead"). It is useful for me now and mature executable signing and verification could rise from further IMA development.
TH
+1  A: 

The DigSig kernel module implements verification of binaries signed by a tool called bsign. However, there hasn't been any work on it since version 2.6.21 of the Linux kernel.

hillu
This response is what I'm looking for: kernel-based binary certification. Unfortunately, DigSig is no longer maintained. My conclusion is nowadays we don't have any production-level solution on kernel based executable certification. Thanks all for the discussion.
TH
Perhaps it is possible to port DigSig to recent kernel versions. My gut feeling tells me that ELF handling can't have changed that much in the last two years.
hillu
@viraptor has a nice answer below, IMA, but I had to pick only one.
TH
+2  A: 

http://en.wikipedia.org/wiki/PKCS

Use a PKCS7 (S/MIME) sign of it. Generate your own cert/private key pair, self-sign the cert and then sign your file with the private key and cert using PKCS7. It'll attach the cert to it, and then it can check itself at runtime using the openssl command (man smime or just do openssl help). This is tamperproof because even though the public key is in the files you give out, the S/MIME signature for that public key can only be generated with the private key which you won't distribute. So if the file is signed by your cert, it must have been signed by someone with the private key and since you didn't give the private key to anyone, it must have come from you.

Here's how to make the self-signed certificate.

http://www.akadia.com/services/ssh%5Ftest%5Fcertificate.html

You'll have to convince openssl to trust your cert as a root of authority (-CAfile), then check it with that as the root, and also check the cert on the file is yours (hash the cert) and check the hash. Note that although it isn't documented, the exit status of openssl reflects the validity of the sign you are checking when doing an smime verify. It's 0 if it matches, non-zero if it doesn't.

Note that all of this is not secure because if the check is in your code, they can simply remove the check if they want to beat you. The only secure way to do it would be to have the checker in the OS and have it check your binary and refuse to run it if it isn't signed. But since there is no checker in the OS and linux can be modified to remove/bypass it anyway... What this is really good for is just detecting corrupt files more than trying to keep people from bypassing you.

Southern Hospitality
This answer tells how to sign and verify a signature but not how to ensure that only verified, signed executables are executed by the linux kernel.
Jamey Hicks