[ioquake3] 100/136: Autoupdater now checks RSA digital signature for manifest.
Simon McVittie
smcv at debian.org
Thu Jun 15 09:09:15 UTC 2017
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to branch debian/master
in repository ioquake3.
commit e04bfd49676b5ed88abc930befb7724c171abb35
Author: Ryan C. Gordon <icculus at icculus.org>
Date: Sun Jun 4 01:32:10 2017 -0400
Autoupdater now checks RSA digital signature for manifest.
---
code/autoupdater/autoupdater.c | 74 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 73 insertions(+), 1 deletion(-)
diff --git a/code/autoupdater/autoupdater.c b/code/autoupdater/autoupdater.c
index fcaf006..d7aa51d 100644
--- a/code/autoupdater/autoupdater.c
+++ b/code/autoupdater/autoupdater.c
@@ -7,6 +7,7 @@ is licensed under the GPLv2. Do not mingle code, please!
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
+#include <errno.h>
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef __int64 int64_t;
@@ -40,6 +41,8 @@ typedef pid_t PID;
#define LTC_NO_ROLC
#include "tomcrypt.h"
+#define PUBLICKEY_FNAME "updater-publickey.bin"
+#define SALT_LEN 8
static int sha256_hash_index = 0;
@@ -599,11 +602,80 @@ static void parseManifest(const char *fname)
fclose(io);
}
+static void read_file(const char *fname, void *buf, unsigned long *len)
+{
+ ssize_t br;
+ FILE *io = fopen(fname, "rb");
+ if (!io) {
+ infof("Can't open '%s' for reading: %s", fname, strerror(errno));
+ die("Failed to read file");
+ }
+
+ br = fread(buf, 1, *len, io);
+ if (ferror(io)) {
+ infof("Couldn't read '%s': %s", fname, strerror(errno));
+ die("Failed to read file");
+ } else if (!feof(io)) {
+ infof("Buffer too small to read '%s'", fname);
+ die("Failed to read file");
+ }
+ fclose(io);
+
+ *len = (unsigned long) br;
+}
+
+static void read_rsakey(rsa_key *key, const char *fname)
+{
+ unsigned char buf[4096];
+ unsigned long len = sizeof (buf);
+ int rc;
+
+ read_file(fname, buf, &len);
+
+ if ((rc = rsa_import(buf, len, key)) != CRYPT_OK) {
+ infof("rsa_import for '%s' failed: %s", fname, error_to_string(rc));
+ die("Couldn't import public key");
+ }
+}
+
+static void verifySignature(const char *fname, const char *sigfname, const char *keyfname)
+{
+ rsa_key key;
+ unsigned char hash[256];
+ unsigned long hashlen = sizeof (hash);
+ unsigned char sig[1024];
+ unsigned long siglen = sizeof (sig);
+ int status = 0;
+ int rc = 0;
+
+ read_rsakey(&key, keyfname);
+ read_file(sigfname, sig, &siglen);
+
+ if ((rc = hash_file(sha256_hash_index, fname, hash, &hashlen)) != CRYPT_OK) {
+ infof("hash_file for '%s' failed: %s", fname, error_to_string(rc));
+ die("Couldn't verify manifest signature");
+ }
+
+ if ((rc = rsa_verify_hash(sig, siglen, hash, hashlen, sha256_hash_index, SALT_LEN, &status, &key)) != CRYPT_OK) {
+ infof("rsa_verify_hash for '%s' failed: %s", fname, error_to_string(rc));
+ die("Couldn't verify manifest signature");
+ }
+
+ if (!status) {
+ infof("Invalid signature for '%s'! Don't trust this file!", fname);
+ die("Manifest is incomplete, corrupt, or compromised");
+ }
+
+ rsa_free(&key);
+}
+
static void downloadManifest(void)
{
const char *manifestfname = "updates/manifest.txt";
+ const char *manifestsigfname = "updates/manifest.txt.sig";
downloadURL("manifest.txt", manifestfname);
- /* !!! FIXME: verify manifest download is complete... */
+ downloadURL("manifest.txt.sig", manifestsigfname);
+ verifySignature(manifestfname, manifestsigfname, PUBLICKEY_FNAME);
parseManifest(manifestfname);
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/ioquake3.git
More information about the Pkg-games-commits
mailing list