Canonical way to sign (and verify) an ELF file? - linux

I would like to sign ELF files, preferably with a PGP key and later be able to verify the signature. Failing that I'll also go with a Authenticode or SSL certificate for signing if that makes more sense. Existing options, such as signelf, seem to be only available under copyleft licenses (even if it's the LGPL, but it imposes restrictions that prevent me from using it) or old/unmaintained.
What options do I have that can be used in a proprietary program?
Note: we can limit the scope of the question to Linux even though ELF isn't particular to Linux.
Even if there is no ready to use program and/or library under a liberal (non-copyleft) FLOSS license, I would appreciate pointers to standardization documents in case some kind of de-facto standard has emerged. I'm not aware of one, but then that's the reason I ask.
From what I see all distros seem to rely on signing the packages and verify these. That's fine in general but I would like to take it a step further.

Related

Statically linked openssl, where are the CA certificate loaded from?

I'm trying to fix an old binary (sources unavailable of course...) that fails to connect now, probably because it's using outdated list of CAs.
However, when running through strace I don't see the binary attempting to read my CAs from /etc/ssl/certs.
Is it possible the list of CAs has been bundled into the binary itself ?
Thanks a lot,
Adam
To be clear, since you say source unavailable I assume you mean a custom program that uses OpenSSL library, since the source for the utility commandline-interface progam named openssl is still available for versions dating back to last century (and until 1.1.0 didn't change much, even when it probably should have).
Yes, definitely. A program using libssl (and libcrypto) can choose whether to use the standard file(s) for its truststore, or some other (custom) file(s) it specifies (often from configuration), or hardcoded data as you ask or data from some other source like a (secure, we hope!) database, or even no truststore at all if it uses ciphersuites that don't use certificate authentication -- anonymous, PSK or SRP -- which is rarely used but is supported by OpenSSL.
You might try strings on the program to see if they were basic enough to embed certs (and maybe other things) in PEM -- IINM that's how Lenovo Superfish was found. If they embedded binary 'DER', that still has enough redundancy you could find it, but not so easily.
Look at the network traffic with Wireshark or similar, or if you have access to the server check its logs, to see if the program is sending an alert in the range 41 to 49 in response to the server's first flight i.e. just after ServerHelloDone.
That would definitively indicate a certificate problem.

Securing symmetric key

In my project (windows desktop application) I use symmetric key in order to encrypt/decrypt some configurations that need to be protected. The key is hardcoded in my code (C++).
What are the risks that my key will be exposed by reverse engineering ? (the customers will receive the compiled DLL only)
Is there a way for better security for managing the key?
Are there open source or commercial products which I can use
Windows provides a key storage mechanism as part of the Crypto API. This would only be useful for you if you have your code generate a unique random key for each user. If you are using a single key for installations for all users, it will obviously have to be in your code (or be derived from constants that are in your code), and thus couldn't really be secure.
What are the risks that my key will be exposed by reverse engineering ? (the customers will receive the compiled DLL only)
100%. Assuming of course that the key protects something useful and interesting. If it doesn't, then lower.
Is there a way for better security for managing the key?
There's no security tool you could use, but there are obfuscation and DRM tools (which are a different problem than security). Any approach you use will need to be updated regularly to deal with new attacks that defeat your old approach. But fundamentally this is the same as DRM for music or video or games or whatever. I would shop around. Anything worthwhile will be regularly updated, and likely somewhat pricey.
Are there open source or commercial products which I can use
Open source solutions for this particular problem are... probably unhelpful. The whole point of DRM is obfuscation (making things confusing and hidden rather than secure). If you share "the secret sauce" then you lose the protection. This is how DRM differs from security. In security, I can tell you everything but the secret, and it's still secure. But DRM, I have to hide everything. That said, I'm sure there are some open source tools that try. There are open source obfuscation tools that try to make it hard to debug the binary by scrambling identifiers and the like, but if there's just one small piece of information that's needed (the configuration), it's hard to obfuscate that sufficiently.
If you need this, you'll likely want a commercial solution, which will be imperfect and likely require patching as it's broken (again, assuming that it protects something that anyone really cares about). Recommending specific solutions is off-topic for Stack Overflow, but google can help you. There are some things specific for Windows that may help, but it depends on your exact requirements.
Keep in mind that the "attacker" (it's hard to consider an authorized user an "attacker") doesn't have to actually get your keys. They just have to wait until your program decrypts the configurations, and then read the configurations out of memory. So you'll need obfuscation around that as well. It's a never-ending battle that you'll have to decide how hard you want to fight.

Can a running nodejs application cryptographically prove it is the same as published source code version?

Can a running nodejs program cryptographically prove that it is the same as a published source code version in a way that could not be tampered with?
Said another way, is there a way to ensure that the commands/code executed by a nodejs program are all and only the commands and code specified in a publicly disclosed repository?
The motivation for this question is the following: In an age of highly sophisticated hackers as well as pressures from government agencies for "backdoors" that allow them to snoop on private transactions and exchanges, can we ensure that an application has been neither been hacked nor had a backdoor added?
As an example, consider an open source-based nodejs application like lesspass (lesspass/lesspass on github) which is used to manage passwords and available for use here (https://lesspass.com/#/).
Or an alternative program for a similar purpose encryptr (SpiderOak/Encryptr on github) with its downloadable version (https://spideroak.com/solutions/encryptr).
Is there a way to ensure that the versions available on their sites to download/use/install are running exactly the same code as is presented in the open source code?
Even if we have 100% faith in the integrity of the the teams behind applications like these, how can we be sure they have not been coerced by anyone to alter the running/downloadable version of their program to create a backdoor for example?
Thank you for your help with this important issue.
sadly no.
simple as that.
the long version:
you are dealing with the outputs of a program, and want to ensure that the output is generated by a specific version of one specific program
lets check a few things:
can an attacker predict the outputs of said program?
if we are talking about open source programs, yes, an attacker can predict what you are expecting to see and even can reproduce all underlying crypto checks against the original source code, or against all internal states of said program
imagine running the program inside a virtual machine with full debugging support like firing up events at certain points in code, directly reading memory to extract cryptographic keys and so on. the attacker does not even have to modify the program, to be able to keep copys of everything you do in plaintext
so ... even if you could cryptographically make sure that the code itself was not tampered with, it would be worth nothing: the environment itself could be designed to do something harmful, and as Maarten Bodewes wrote: in the end you need to trust something.
one could argue that TPM could solve this but i'm afraid of the world that leads to: in the end ... you still have to trust something like a manufacturer or worse a public office signing keys for TPMs ... and as we know those would never... you hear? ... never have other intentions than what's good for you ... so basically you wouldn't win anything with a centralized TPM based infrastructure
You can do this cryptographically by having a runtime that checks signatures before running any code. Of course, you'd have to trust that runtime environment as well. Unless you have such an environment you're out of luck - that is, unless you do a full code review.
Furthermore you can sign the build by placing a signature within the build system. The build system and developer access in turn can be audited. This is usually how secure development environments are build. But in the end you need to trust something.
If you're just afraid that a particular download is corrupted you can test against an official hash published at one or more trusted locations.

Encryption and code archive files

We have this computer code which requires anyone who has access to it pay a license fee. We will pay the fee for our developers but they want our sysadmins to be licensed too as they can see the code archives. But if the code is stored encrypted in the archives then the sysadmins can see the files but not see the contents.
So does any software version control system allow encryption so that only the persons who are checking out the code will require the key and so be able to see the files decrypted.
I was thinking it wouldn't be hard to add this to pserver and cvs but if it is already done elsewhere why reinvent the wheel.
Any insight would be helpful.
There is no way to set up a source control system that can perform server-side diffs in a way that would prevent a sysadmin from at least theoretically accessing the contents. (i.e.: The source control system would not be able to store the decryption key in a place that the sysadmin couldn't access.) Unless your sysadmins habitually browse the source control database contents, such a system should have no practical difference from an unencrypted system from the perspective of your vendor.
The only way to make the source control database illegible to a server admin is to encrypt files on the client before submitting them to the server. For this to meet the desired goal, the decryption keys would need to be inaccessible to the admins, which is unlikely to be practical in most organizations since server admins typically have admin access on all client machines as well. Ignoring this picky detail, it would also mean that all your source control system would ever see is encrypted binaries, which means no server-side diff or blame. It also means potentially horrible bloat of your database size since every file will require complete replacement on each commit. Are you really willing to sacrifice useability of your source control system in order to save licensing fees and/or placate this vendor?
Basically, you want to give all your developers some secret key that they plug into the encryption/decryption routines of git's smudge and clean filters. And you want an encryption scheme that is capable of performing deltas.
First, see Encrypted version control for some examples in git. As written, this can dramatically increase disk usage. However, there are ways to make more "diff-friendly" encryption at the cost of some security. See diph for an example of how you might attack that. Also, any system that uses AES-ECB mode would diff quite well. (You generally shouldn't use AES-ECB mode because of its security flaws... one of those security flaws is that it can diff quite well... hey, that's what you wanted, so this seems a reasonable exception.)

What is the best way to encrypt a text file in C/C++?

A C/C++ based cgi web application will be creating a temporary text file on the server as long as the user is logged in. The text file will be deleted when the user logs off. I want to encrypt this text file and also the content of the file. The file will contain information like username and password.
What is the best way to do this?
EDIT: I see libraries being suggested. My problem is I cannot use anything but Standard C++ library.
Use a well known library such as openssl and follow well known examples and stay away from platform specific solutions.
I think you might be going about this the wrong way. If security, real security, is the goal then you're not going to want to store the password even in its encrypted form (because it can be decrypted if the key is stolen, as other people have said).
What you should do is store a hash of the password (with an appropriate salt). This means that no one (not even the site admins) can determine a user's password. They can merely accept a password and see if it's the right one or not by hashing the input with the same salt (you can't reverse a hash).
Also, this sort of situation lends itself nicely to databases, are you using one?
Google password hashing with salts and you can read about it from real security experts (I am not one).
An encryption standard that currently is considered as "safe" is AES (also called Rijndael). You can find a C++ implementation at Codeproject and in many other places.
Please note, that when using AES or any other symmetric encryption standard, you must store the encryption/decryption key inside your application. If anyone discovers the key, he can decrypt all files that you encrypted with this key.
If your application will run under Windows, you also might use DPAPI to store the encrypted information.
Revised answer.
You want code to encrypt and decrypt a file that can be used with your C++ code.
It would be absolutely incorrect to write your own code (like this one).
But, you say that you cannot use standard libraries.
Standard (and, maybe opensource) libraries are probably the most correct approach to implementing encryption in your applications. If you choose to not do that, it leaves you with only two options,
Implement your own version of a standard encryption algorithm (and risk weakness by any errors you make)
Use a 'system' call from your application and run a standard encryption (like bcrypt) that maybe (hopefully) available on your system.
I would still stick to picking up a standard library or integrating such an opensource code into my application. Please explain what prevents you from doing that.
Old: for some reason, i thought a PHP code was required... my error.
This article gives a PHP encryption symmetric program example using crypt to store password in a text file.
Possibly related Stackoverflow questions
discussion on the best C/C++ encryption library.
discussion on plain text storage of password.

Resources