]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Drop support for checksums
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 23 Aug 2022 15:24:03 +0000 (15:24 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 23 Aug 2022 15:24:03 +0000 (15:24 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c

index 4a1d3485177f068a2f3d0b8bf3a8f09e625ed6aa..6cf8e944ed4724575b7fa1446d2e817cf47a164d 100644 (file)
 #include <pakfire/string.h>
 #include <pakfire/util.h>
 
-static const char* pakfire_archive_files_without_chksums[] = {
-       "pakfire-format",
-       "chksums",
-       NULL,
-};
-
-struct pakfire_archive_chksum {
-       STAILQ_ENTRY(pakfire_archive_chksum) nodes;
-
-       char path[PATH_MAX];
-
-       unsigned char digest_sha512[64];
-       unsigned char digest_sha256[32];
-};
-
 struct pakfire_archive {
        struct pakfire* pakfire;
        int nrefs;
@@ -89,9 +74,6 @@ struct pakfire_archive {
 
        struct pakfire_filelist* filelist;
 
-       // Checksums
-       STAILQ_HEAD(chksums, pakfire_archive_chksum) chksums;
-
        // Scriptlets
        struct pakfire_scriptlet** scriptlets;
        int scriptlets_loaded;
@@ -110,7 +92,6 @@ static const char* pakfire_archive_legacy_filename(
                const char* file;
                const char* legacy;
        } filenames[] = {
-               { "CHKSUMS",  "chksums" },
                { "DATA",     "data.img" },
                { "FILELIST", "filelist"},
                { "PKGINFO",  "info" },
@@ -351,98 +332,11 @@ ERROR:
        return NULL;
 }
 
-// Checksum Stuff
-
-static int pakfire_archive_add_chksum(struct pakfire_archive* archive, const char* path,
-               const unsigned char* digest_sha512, const unsigned char* digest_sha256) {
-       int r = 1;
-
-       // Path must be set
-       if (!path) {
-               errno = EINVAL;
-               return 1;
-       }
-
-       // At least one of the digests must be set
-       if (!digest_sha512 && !digest_sha256) {
-               errno = EINVAL;
-               return 1;
-       }
-
-       // Allocate a new chksum object
-       struct pakfire_archive_chksum* chksum = calloc(1, sizeof(*chksum));
-       if (!chksum)
-               return ENOMEM;
-
-       // Store path
-       r = pakfire_string_set(chksum->path, path);
-       if (r)
-               goto ERROR;
-
-       // SHA512
-       if (digest_sha512)
-               memcpy(chksum->digest_sha512, digest_sha512, sizeof(chksum->digest_sha512));
-
-       // SHA256
-       if (digest_sha256)
-               memcpy(chksum->digest_sha256, digest_sha256, sizeof(chksum->digest_sha256));
-
-       // Append it
-       STAILQ_INSERT_TAIL(&archive->chksums, chksum, nodes);
-
-       DEBUG(archive->pakfire, "Added checksum for %s\n", path);
-
-       return 0;
-
-ERROR:
-       free(chksum);
-
-       return r;
-}
-
-static struct pakfire_archive_chksum* pakfire_archive_find_chksum(
-               struct pakfire_archive* archive, const char* path) {
-       struct pakfire_archive_chksum* chksum = NULL;
-
-       STAILQ_FOREACH(chksum, &archive->chksums, nodes) {
-               if (strcmp(chksum->path, path) == 0)
-                       return chksum;
-       }
-
-       // Nothing found
-       return NULL;
-}
-
-static int __pakfire_archive_chksum_has_digest(const unsigned char* digest, const size_t length) {
-       for (unsigned int i = 0; i < length; i++) {
-               if (digest[i])
-                       return 1;
-       }
-
-       return 0;
-}
-
-#define pakfire_archive_chksum_has_digest(digest) \
-       __pakfire_archive_chksum_has_digest(digest, sizeof(digest))
-
-static void pakfire_archive_free_chksums(struct pakfire_archive* archive) {
-       struct pakfire_archive_chksum* chksum;
-
-       while ((chksum = STAILQ_FIRST(&archive->chksums))) {
-               STAILQ_REMOVE_HEAD(&archive->chksums, nodes);
-
-               free(chksum);
-       }
-}
-
 static void pakfire_archive_free(struct pakfire_archive* archive) {
        // Close the file
        if (archive->f)
                fclose(archive->f);
 
-       // Free all checksums
-       pakfire_archive_free_chksums(archive);
-
        // Free scriptlets
        if (archive->scriptlets) {
                for (struct pakfire_scriptlet** scriptlet = archive->scriptlets; *scriptlet; scriptlet++)
@@ -470,10 +364,7 @@ static int pakfire_archive_create(struct pakfire_archive** archive, struct pakfi
        a->pakfire = pakfire_ref(pakfire);
        a->nrefs = 1;
 
-       STAILQ_INIT(&a->chksums);
-
        *archive = a;
-
        return 0;
 }
 
@@ -932,413 +823,8 @@ PAKFIRE_EXPORT struct pakfire_filelist* pakfire_archive_get_filelist(struct pakf
        return pakfire_filelist_ref(archive->filelist);
 }
 
-static int pakfire_archive_load_checksums_mtree(struct pakfire_archive* archive) {
-       struct archive* a = NULL;
-       struct archive_entry* entry = NULL;
-       int r;
-
-       // Find chksums
-       r = open_archive_and_find(archive, &a, &entry, "FILELIST");
-       if (r)
-               return r;
-
-       // Allocate a new archive reader
-       struct archive* mtree = archive_read_new();
-       if (!mtree) {
-               ERROR(archive->pakfire, "Could not allocate mtree reader\n");
-               goto ERROR;
-       }
-
-       // Enable reading the mtree format
-       r = archive_read_support_format_mtree(mtree);
-       if (r) {
-               ERROR(archive->pakfire, "Could not enable mtree format: %s\n",
-                       archive_error_string(mtree));
-               goto ERROR;
-       }
-
-       // Filelists can be Zstandard-compressed
-       r = archive_read_support_filter_zstd(mtree);
-       if (r)
-               goto ERROR;
-
-       // Try opening the mtree
-       r = archive_read_open2(mtree, a, NULL, pakfire_archive_read_callback, NULL, NULL);
-       if (r) {
-               ERROR(archive->pakfire, "Could not open checksum mtree in %s: %s\n",
-                       archive->path, archive_error_string(mtree));
-               goto ERROR;
-       }
-
-       for (;;) {
-               // Read next entry
-               r = archive_read_next_header(mtree, &entry);
-
-               // We have reached the end of the list
-               if (r == ARCHIVE_EOF)
-                       break;
-
-               // An unexpected error has occurred
-               else if (r) {
-                       ERROR(archive->pakfire, "Could not read mtree entry: %s\n",
-                               archive_error_string(mtree));
-                       goto ERROR;
-               }
-
-               // Fetch pathname
-               const char* path = archive_entry_pathname(entry);
-
-               // Fetch all supported digests
-               const unsigned char* digest_sha512 = archive_entry_digest(
-                       entry, ARCHIVE_ENTRY_DIGEST_SHA512);
-               const unsigned char* digest_sha256 = archive_entry_digest(
-                       entry, ARCHIVE_ENTRY_DIGEST_SHA256);
-
-               // Add the checksum to the internal list
-               r =  pakfire_archive_add_chksum(archive, path + 2, digest_sha512, digest_sha256);
-               if (r)
-                       goto ERROR;
-       }
-
-       // Success
-       r = 0;
-
-ERROR:
-       if (mtree)
-               archive_read_free(mtree);
-       close_archive(archive, a);
-
-       return r;
-}
-
-static int pakfire_archive_load_checksums_legacy_line(
-               struct pakfire_archive* archive, char* line) {
-       char path[PATH_MAX] = "";
-       char hexdigest[LINE_MAX] = "";
-       char* tok = NULL;
-
-       unsigned int i = 0;
-       int r = 1;
-
-       char* word = strtok_r(line, " ", &tok);
-       while (word) {
-               switch (i) {
-                       // path
-                       case 0:
-                               r = pakfire_string_set(path, word);
-                               if (r)
-                                       return r;
-                               break;
-
-                       // hexdigest
-                       case 1:
-                               r = pakfire_string_set(hexdigest, word);
-                               if (r)
-                                       return r;
-                               break;
-
-                       default:
-                               ERROR(archive->pakfire, "Invalid line in checksums:\n%s\n", line);
-                               r = 1;
-                               return r;
-               }
-
-               word = strtok_r(NULL, " ", &tok);
-               i++;
-       }
-
-       // Check if we have input for path and hexdigest
-       if (!*path || !*hexdigest) {
-               errno = EINVAL;
-               return r;
-       }
-
-       unsigned char digest[EVP_MAX_MD_SIZE];
-
-       // Convert hexdigest to digest
-       r = pakfire_unhexlify(digest, hexdigest);
-       if (r)
-               return r;
-
-       // Add a chksum object
-       r = pakfire_archive_add_chksum(archive, path, digest, NULL);
-       if (r)
-               return r;
-
-       // Success
-       return 0;
-}
-
-static int pakfire_archive_load_checksums_legacy(struct pakfire_archive* archive) {
-       char* buffer = NULL;
-       size_t length = 0;
-
-       // Find chksums
-       int r = open_archive_and_read(archive, "CHKSUMS", &buffer, &length);
-       if (r)
-               return r;
-
-       // Empty file
-       if (!length) {
-               ERROR(archive->pakfire, "Checksums file was unexpectedly empty\n");
-               return 1;
-       }
-
-       char line[LINE_MAX];
-       char* l = line;
-
-       // Split the input into lines and call pakfire_archive_load_checksums_legacy_line
-       for (char* p = buffer; (size_t)(p - buffer) < length; p++) {
-               if (*p == '\n' || p == (buffer + length)) {
-                       // Terminate line
-                       *l = '\0';
-
-                       // Process the line
-                       r = pakfire_archive_load_checksums_legacy_line(archive, line);
-                       if (r)
-                               goto ERROR;
-
-                       // Reset line pointer
-                       l = line;
-
-                       continue;
-               }
-
-               // Copy character to line
-               *l++ = *p;
-
-               // Check if line has enough space
-               if ((size_t)(l - line) >= sizeof(line)) {
-                       errno = ENOBUFS;
-                       goto ERROR;
-               }
-       }
-
-ERROR:
-       if (buffer)
-               free(buffer);
-       return r;
-}
-
-static int pakfire_archive_load_checksums(struct pakfire_archive* archive) {
-       // Do nothing if the list has already been loaded
-       if (!STAILQ_EMPTY(&archive->chksums))
-               return 0;
-
-       DEBUG(archive->pakfire, "Loading checksums from archive %p\n", archive);
-
-       if (archive->format >= 6)
-               return pakfire_archive_load_checksums_mtree(archive);
-       else
-               return pakfire_archive_load_checksums_legacy(archive);
-}
-
-struct pakfire_archive_validator {
-       EVP_MD_CTX* ctx;
-       const unsigned char* digest;
-};
-
-static int pakfire_archive_verify_add_validator(struct pakfire_archive_validator*** list,
-               struct pakfire* pakfire, const EVP_MD* md, const unsigned char* digest) {
-       // Allocate validator
-       struct pakfire_archive_validator* v = calloc(1, sizeof(*v));
-       if (!v)
-               return 1;
-
-       int r = 1;
-
-       // Allocate an EVP context
-       v->ctx = EVP_MD_CTX_new();
-       if (!v->ctx) {
-               ERROR(pakfire, "Could not allocate an EVP context\n");
-               goto ERROR;
-       }
-
-       // Initialise the hash algorithm
-       r = EVP_DigestInit_ex(v->ctx, md, NULL);
-       if (r != 1) {
-               ERROR(pakfire, "Could not initialize hash algorithm: %s\n",
-                       ERR_error_string(ERR_get_error(), NULL));
-               r = 1;
-               goto ERROR;
-       }
-
-       // Store digest
-       v->digest = digest;
-
-       unsigned int counter = 0;
-
-       // Calculate list size
-       if (*list) {
-               for (struct pakfire_archive_validator** l = *list; *l; l++)
-                       counter++;
-       }
-
-       // Grow list
-       *list = reallocarray(*list, counter + 2, sizeof(**list));
-       if (!*list) {
-               r = 1;
-               goto ERROR;
-       }
-
-       // Append validator
-       (*list)[counter] = v;
-
-       // Terminate list
-       (*list)[counter + 1] = NULL;
-
-       // Success
-       return 0;
-
-ERROR:
-       if (v->ctx)
-               EVP_MD_CTX_free(v->ctx);
-       free(v);
-
-       return r;
-}
-
-static int pakfire_archive_verify_file(struct pakfire_archive* archive,
-               struct archive* a, struct archive_entry* entry, void* data) {
-       const char* path = archive_entry_pathname(entry);
-
-       // Some files do not have checksums
-       for (const char** file = pakfire_archive_files_without_chksums; *file; file++) {
-               if (strcmp(*file, path) == 0)
-                       return 0;
-       }
-
-       // Fetch the checksum
-       struct pakfire_archive_chksum* chksum = pakfire_archive_find_chksum(archive, path);
-       if (!chksum) {
-               ERROR(archive->pakfire, "No checksum found for %s\n", path);
-               return 1;
-       }
-
-       struct pakfire_archive_validator** validators = NULL;
-       int r;
-
-       // SHA512
-       if (pakfire_archive_chksum_has_digest(chksum->digest_sha512)) {
-               r = pakfire_archive_verify_add_validator(&validators, archive->pakfire,
-                       EVP_sha512(), chksum->digest_sha512);
-               if (r)
-                       return r;
-       }
-
-       // SHA256
-       if (pakfire_archive_chksum_has_digest(chksum->digest_sha256)) {
-               r = pakfire_archive_verify_add_validator(&validators, archive->pakfire,
-                       EVP_sha256(), chksum->digest_sha256);
-               if (r)
-                       return r;
-       }
-
-       // Check if anything was selected (this should not happen)
-       if (!validators) {
-               ERROR(archive->pakfire, "No validators selected\n");
-               return 1;
-       }
-
-       DEBUG(archive->pakfire, "Verifying %s\n", path);
-
-       const void* buffer = NULL;
-       size_t size = 0;
-       off_t offset = 0;
-
-       // Read the payload of the file and feed it into the validators
-       for (;;) {
-               r = archive_read_data_block(a, &buffer, &size, &offset);
-               if (r == ARCHIVE_EOF)
-                       break;
-
-               // End on any errors
-               if (r) {
-                       r = 1;
-                       goto ERROR;
-               }
-
-               // Update all hash digests
-               for (struct pakfire_archive_validator** v = validators; *v; v++) {
-                       r = EVP_DigestUpdate((*v)->ctx, buffer, size);
-                       if (r != 1) {
-                               ERROR(archive->pakfire, "%s\n", ERR_error_string(ERR_get_error(), NULL));
-                               r = 1;
-                               goto ERROR;
-                       }
-               }
-       }
-
-       unsigned char digest[EVP_MAX_MD_SIZE];
-
-       // Finalize all digests
-       for (struct pakfire_archive_validator** v = validators; *v; v++) {
-               // Reset digest array size
-               unsigned int length = sizeof(digest);
-
-               // Finish computation
-               r = EVP_DigestFinal_ex((*v)->ctx, digest, &length);
-               if (r != 1) {
-                       ERROR(archive->pakfire, "%s\n", ERR_error_string(ERR_get_error(), NULL));
-                       r = 1;
-                       goto ERROR;
-               }
-
-               // Compare digests
-               r = CRYPTO_memcmp(digest, (*v)->digest, length);
-
-               // Handle mismatches
-               if (r) {
-                       ERROR(archive->pakfire, "Checksum of %s did not match\n", chksum->path);
-
-                       char* hexdigest_expected = pakfire_hexlify((*v)->digest);
-                       if (hexdigest_expected) {
-                               ERROR(archive->pakfire, "  Expected: %s\n", hexdigest_expected);
-                               free(hexdigest_expected);
-                       }
-
-                       char* hexdigest_computed = pakfire_hexlify(digest);
-                       if (hexdigest_computed) {
-                               ERROR(archive->pakfire, "  Computed: %s\n", hexdigest_computed);
-                               free(hexdigest_computed);
-                       }
-
-                       goto ERROR;
-               }
-       }
-
-       DEBUG(archive->pakfire, "All (checked) checksums of %s matched\n", chksum->path);
-
-       // Success
-       r = 0;
-
-ERROR:
-       if (validators) {
-               for (struct pakfire_archive_validator** v = validators; *v; v++) {
-                       EVP_MD_CTX_free((*v)->ctx);
-                       free(*v);
-               }
-               free(validators);
-       }
-
-       return r;
-}
-
 PAKFIRE_EXPORT int pakfire_archive_verify(struct pakfire_archive* archive, int* status) {
-       int r;
-
-       // Read checksums from archive
-       r = pakfire_archive_load_checksums(archive);
-       if (r)
-               return r;
-
-       // Iterate over all files and verify them if a checksum is present
-       r = pakfire_archive_walk(archive, pakfire_archive_verify_file, NULL);
-       if (r) {
-               ERROR(archive->pakfire, "File verification failed\n");
-               return r;
-       }
-
+       // XXX currently not implemented
        return 0;
 }