]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Improve verification speed
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 13 Jul 2021 11:47:35 +0000 (11:47 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 13 Jul 2021 11:47:35 +0000 (11:47 +0000)
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 <michael.tremer@ipfire.org>
src/libpakfire/archive.c

index 26ae04318c9ba7e9991a7d794caac1251553e1ec..e1f35168382feccbb1688cdca42fef3a4dc7ffda 100644 (file)
 #include <pakfire/scriptlet.h>
 #include <pakfire/util.h>
 
+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;