]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Store OpenSSL context in main struct
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 8 Mar 2021 00:16:31 +0000 (00:16 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 8 Mar 2021 00:16:31 +0000 (00:16 +0000)
This avoids allocating and freeing a new context for every file that is
being hashed.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c

index eb05acb3e4a1519995f42245923e3094a71f9877..eb5000b640ea67bd488d5f3bca7e6d436b6bf00a 100644 (file)
@@ -81,6 +81,9 @@ struct _PakfireArchive {
        struct pakfire_scriptlet** scriptlets;
        size_t nscriptlets;
 
+       // OpenSSL
+       EVP_MD_CTX* mdctx;
+
        int nrefs;
 };
 
@@ -342,6 +345,10 @@ PAKFIRE_EXPORT PakfireArchive pakfire_archive_ref(PakfireArchive archive) {
 static void pakfire_archive_free(PakfireArchive archive) {
        DEBUG(archive->pakfire, "Releasing archive at %p\n", archive);
 
+       // Release OpenSSL context
+       if (archive->mdctx)
+               EVP_MD_CTX_free(archive->mdctx);
+
        if (archive->path)
                free(archive->path);
 
@@ -617,17 +624,28 @@ PAKFIRE_EXPORT char* pakfire_archive_get(PakfireArchive archive, const char* nam
        return pakfire_parser_get(archive->parser, namespace, key);
 }
 
-static int archive_copy_data(Pakfire pakfire, struct archive* in, struct archive* out,
+static int archive_copy_data(PakfireArchive archive, struct archive* in, struct archive* out,
                char** hexdigest) {
-       EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
+       int r;
+
+       // Create or reset OpenSSL context
+       if (archive->mdctx) {
+               r = EVP_MD_CTX_reset(archive->mdctx);
+               if (r != 1) {
+                       ERROR(archive->pakfire, "Could not reset EVP_MD_CTX: %s\n",
+                               ERR_error_string(ERR_get_error(), NULL));
+                       return 1;
+               }
+       } else {
+               archive->mdctx = EVP_MD_CTX_new();
+       }
 
        // Initialize digest
-       int r = EVP_DigestInit_ex(mdctx, EVP_blake2s256(), NULL);
+       r = EVP_DigestInit_ex(archive->mdctx, EVP_blake2s256(), NULL);
        if (r != 1) {
-               ERROR(pakfire, "Could not setup digest function: %s\n",
+               ERROR(archive->pakfire, "Could not setup digest function: %s\n",
                        ERR_error_string(ERR_get_error(), NULL));
-               r = 1;
-               goto ERROR;
+               return 1;
        }
 
        const void* buffer;
@@ -641,55 +659,47 @@ static int archive_copy_data(Pakfire pakfire, struct archive* in, struct archive
                        break;
 
                if (r != ARCHIVE_OK) {
-                       ERROR(pakfire, "Could not read data from archive: %s\n",
+                       ERROR(archive->pakfire, "Could not read data from archive: %s\n",
                                archive_error_string(in));
-                       goto ERROR;
+                       return 1;
                }
 
                // Update digest
-               r = EVP_DigestUpdate(mdctx, buffer, size);
+               r = EVP_DigestUpdate(archive->mdctx, buffer, size);
                if (r != 1) {
-                       ERROR(pakfire, "EVP_DigestUpdate failed: %s\n",
+                       ERROR(archive->pakfire, "EVP_DigestUpdate failed: %s\n",
                                ERR_error_string(ERR_get_error(), NULL));
-                       r = 1;
-                       goto ERROR;
+                       return 1;
                }
 
                // Write the data
                r = archive_write_data_block(out, buffer, size, offset);
                if (r != ARCHIVE_OK) {
-                       ERROR(pakfire, "Could not write data to disk: %s\n",
+                       ERROR(archive->pakfire, "Could not write data to disk: %s\n",
                                archive_error_string(out));
-                       goto ERROR;
+                       return 1;
                }
        }
 
        char digest[EVP_MAX_MD_SIZE];
-       size_t digest_length;
+       size_t digest_length = 0;
 
        // Finalize the digest
-       r = EVP_DigestFinal_ex(mdctx, (unsigned char*)digest, (unsigned int*)&digest_length);
+       r = EVP_DigestFinal_ex(archive->mdctx, (unsigned char*)digest, (unsigned int*)&digest_length);
        if (r != 1) {
-               ERROR(pakfire, "%s\n", ERR_error_string(ERR_get_error(), NULL));
-               goto ERROR;
+               ERROR(archive->pakfire, "%s\n", ERR_error_string(ERR_get_error(), NULL));
+               return 1;
        }
 
        // Convert to hex
        *hexdigest = pakfire_hexlify(digest, digest_length);
 
-       DEBUG(pakfire, "Computed digest of %zu bytes: %s\n", digest_length, *hexdigest);
+       DEBUG(archive->pakfire, "Computed digest of %zu bytes: %s\n", digest_length, *hexdigest);
 
-       // Success
-       r = 0;
-
-ERROR:
-       if (mdctx)
-               EVP_MD_CTX_free(mdctx);
-
-       return r;
+       return 0;
 }
 
-static int archive_extract(Pakfire pakfire, struct archive* a, const char* prefix) {
+static int archive_extract(PakfireArchive archive, struct archive* a, const char* prefix) {
        struct archive_entry* entry;
        int r;
 
@@ -725,7 +735,7 @@ static int archive_extract(Pakfire pakfire, struct archive* a, const char* prefi
                char* pathname = pakfire_path_join(prefix, archive_pathname);
                archive_entry_set_pathname(entry, pathname);
 
-               DEBUG(pakfire, "Extracting %s (%zu bytes)\n", pathname, size);
+               DEBUG(archive->pakfire, "Extracting %s (%zu bytes)\n", pathname, size);
                free(pathname);
 
                // Update hardlink targets
@@ -744,14 +754,14 @@ static int archive_extract(Pakfire pakfire, struct archive* a, const char* prefi
                // Create file
                r = archive_write_header(ext, entry);
                if (r != ARCHIVE_OK) {
-                       ERROR(pakfire, "Could not extract file /%s: %s\n",
+                       ERROR(archive->pakfire, "Could not extract file /%s: %s\n",
                                archive_pathname, archive_error_string(ext));
                        break;
                }
 
                // Copy payload
                if (size > 0) {
-                       r = archive_copy_data(pakfire, a, ext, &hexdigest);
+                       r = archive_copy_data(archive, a, ext, &hexdigest);
                        if (r != ARCHIVE_OK)
                                break;
                }
@@ -768,12 +778,12 @@ static int archive_extract(Pakfire pakfire, struct archive* a, const char* prefi
                                break;
 
                        case ARCHIVE_WARN:
-                               DEBUG(pakfire, "/%s: %s\n",
+                               DEBUG(archive->pakfire, "/%s: %s\n",
                                        archive_pathname, archive_error_string(ext));
                                continue;
 
                        case ARCHIVE_FAILED:
-                               ERROR(pakfire, "/%s: %s\n",
+                               ERROR(archive->pakfire, "/%s: %s\n",
                                        archive_pathname, archive_error_string(ext));
                                break;
                }
@@ -943,7 +953,7 @@ PAKFIRE_EXPORT int pakfire_archive_extract(PakfireArchive archive, const char* p
        if (use_payload)
                pa = archive_open_payload(a);
 
-       r = archive_extract(archive->pakfire, use_payload ? pa : a,
+       r = archive_extract(archive, use_payload ? pa : a,
                prefix ? prefix : pakfire_get_path(archive->pakfire));
 
        if (pa)