I presented a talk about signify at BSDCan on Friday. It went really well; during and after the talk many people told me I was wrong.
Here’s a list of things that are less than perfect, either with the signify tool or with its usage.
Some issues affect the signify tool itself. I’m happy that so far they’re quite minor.
Secret key files contain a 64-bit hash (truncated SHA512) of the secret key data which is used to verify the user’s password. You wouldn’t want to enter the wrong password and accidentally sign something with a bogus key. Unfortunately, this creates something of an oracle. If you steal somebody’s secret key, instead of guessing passwords which will be terribly slow because of the KDF, you can just guess keys and compute hashes until you get a match. The good news is that the key space is fairly large; you won’t have much luck guessing one. Harmless as this may be, it’s bothered me quite a bit because it’s plainly wrong. (The rationale for this decision was that encrypting the hash as well would require another iteration of the KDF.)
Florian Weimer pointed out that fingerprint is a poor term to use, given the conventional understanding of the term. This was easy to fix; the fingerprint field was renamed to keynum.
The file formats are very primitive. This was by design, and it’s sufficient for our purposes, but it’s an impediment to other projects using signify as is. Instead, people are rolling their own similar but slightly different tools.
Other issues affect OpenBSD’s usage of signify. I don’t think they are critical, but they deserve consideration.
The paper A Look In the Mirror covers many attacks against package managers.
We don’t do much to prevent freeze attacks. Obviously, if you want to install 5.7 and your mirror only lists 5.6, you’ll know something is up. pkg_add does do some basic timestamp checking of the quirks metapackage, but I’m not sure it’s sufficient. This is a hard problem to solve completely, especially for a system that’s supposed to work offline. We don’t require an always on timestamp server.
A replay or rollback attack is not possible with packages, as I understand it. The package version will increment from (e.g.) p2 to p3, and pkg_add will not normally consider p2 to be an upgrade to p3. Base releases, however, could be rolled back to a beta snapshot.
signify was intended to prevent the injection of backdoors, not to guarantee you’re absolutely secure. What you install is what we built (at some point), but not necessarily exactly what’s sitting on the build servers today. I think it’s fair to say freeze attacks are out of scope. But that’s a dodge when it comes to rollbacks. Reinjecting a known fixed fault is roughly equivalent to injecting a new backdoor. We should work to do better.
Fixed: Sometime after 5.8 I added a basic BUILDINFO file to the base distribution which includes a timestamp.
The base sets are verified and checksummed before any complex parsing code looks at them. Packages however must be ungzipped and untarred before the signature can be found, since it’s inside the package. There have been buffer overflows in both gzip and tar before, so this is a valid concern. Tough to fix for packages, though, without additional work to ensure consistent external metadata.
Fixed: espie added code to sign gzips and it’s now enabled for pkg_add.
Solutions exist for all of the above in one way or another, but it’s not just a technical matter of somebody writing a new signing script. It involves some policy and process changes as well regarding who signs what and how and when. We had some trouble getting things going as they are; more invasive changes will take time.
I remember talking extensively with Vsevolod Stakhov (asignify author) and Jean-Philippe Ouellet, but I’m terrible with names. Several other people mentioned similar issues, thanks to them too.