Open encryptio opened 8 years ago
For actual implementation, I'd try to avoid using public key crypto primitives directly if possible; they tend to be more subtle than they seem (as Sony found out the hard way with the PS3)
GPG/PGP looks good at first, but it's an additional large external dependency and does not have a programmatic API (even the programmatic API library that exists just does version-based text matching on the output of the gpg
command.)
OpenBSD's signify
(blog post, man page) seems to be a nice, auditably small implementation of "sign/verify this file with this key". There's also a reimplementation of it in Go.
Instead of just giving a URL, version, and checksum for each binary, give a URL, checksum, version, and signature for each binary.
This is to protect against an attacker who somehow gains control over the domain name or the server serving the update metadata file.
To prevent arbitrary binaries, the checksum MUST be part of the signed data. To prevent downgrade attacks, the version field MUST part of the signed data and the updater MUST ignore updates whose versions are not greater than its current version. The URL/filename does not need to be signed, since the checksum completely defines the data that should be accepted by the updater.
We should store the private signing key in a way that it requires a password for every new signature we make, rather than having it be fully on-line. (If it's fully automated and on-line, it's subject to many of the same vulnerabilities as the metadata file server, meaning we gain much less security than desired.)
Followup to #56.