From: Michael Tremer Date: Tue, 13 Jul 2021 11:47:35 +0000 (+0000) Subject: archive: Improve verification speed X-Git-Tag: 0.9.28~1035 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ab9cb5e6271548031fe685d9eba2dc62335ef9a;p=pakfire.git archive: Improve verification speed We validate all checksums before we generate a signature for an archive, but on verification, we only check the best checksum. Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index 26ae04318..e1f351683 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -52,6 +52,11 @@ #include #include +enum pakfire_archive_verify_flags { + PAKFIRE_ARCHIVE_VERIFY_ALL, + PAKFIRE_ARCHIVE_VERIFY_BEST, +}; + struct pakfire_archive_chksum { STAILQ_ENTRY(pakfire_archive_chksum) nodes; @@ -1309,7 +1314,27 @@ struct pakfire_archive_validator { }; static int pakfire_archive_verify_add_validator(struct pakfire_archive_validator*** list, - struct pakfire* pakfire, const EVP_MD* md, const unsigned char* digest) { + struct pakfire* pakfire, const EVP_MD* md, const unsigned char* digest, + enum pakfire_archive_verify_flags flags) { + + switch (flags) { + // Fall through and add the validator + case PAKFIRE_ARCHIVE_VERIFY_ALL: + break; + + // We only accept one validator, so this function becomes a no-op when list + // has any validators already + case PAKFIRE_ARCHIVE_VERIFY_BEST: + if (*list) + return 0; + break; + + default: + errno = EINVAL; + return 1; + } + + // Allocate validator struct pakfire_archive_validator* v = calloc(1, sizeof(*v)); if (!v) return 1; @@ -1384,7 +1409,7 @@ static int pakfire_archive_verify_file(struct pakfire_archive* archive, // SHA512 if (pakfire_archive_chksum_has_digest(chksum->digest_sha512)) { r = pakfire_archive_verify_add_validator(&validators, archive->pakfire, - EVP_sha512(), chksum->digest_sha512); + EVP_sha512(), chksum->digest_sha512, flags); if (r) return r; } @@ -1392,7 +1417,7 @@ static int pakfire_archive_verify_file(struct pakfire_archive* archive, // SHA256 if (pakfire_archive_chksum_has_digest(chksum->digest_sha256)) { r = pakfire_archive_verify_add_validator(&validators, archive->pakfire, - EVP_sha256(), chksum->digest_sha256); + EVP_sha256(), chksum->digest_sha256, flags); if (r) return r; } @@ -1643,7 +1668,7 @@ PAKFIRE_EXPORT int pakfire_archive_verify(struct pakfire_archive* archive, return r; // Verify checksums - r = pakfire_archive_verify_checksums(archive, 0); + r = pakfire_archive_verify_checksums(archive, PAKFIRE_ARCHIVE_VERIFY_BEST); if (r) return r; } @@ -1865,7 +1890,12 @@ static int pakfire_archive_append_signature(struct pakfire_archive* archive, PAKFIRE_EXPORT int pakfire_archive_sign(struct pakfire_archive* archive, struct pakfire_key* key) { int r; - // XXX check if all checksums match + // Verify checksums + r = pakfire_archive_verify_checksums(archive, PAKFIRE_ARCHIVE_VERIFY_ALL); + if (r) { + ERROR(archive->pakfire, "The archive checksums don't match\n"); + return r; + } char* signature = NULL; size_t signature_length = 0;