From: Michael Tremer Date: Mon, 8 Mar 2021 00:16:31 +0000 (+0000) Subject: archive: Store OpenSSL context in main struct X-Git-Tag: 0.9.28~1285^2~610 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=de3dc808eaf56bfa42d480219c7d00eca0f6d1e9;p=pakfire.git archive: Store OpenSSL context in main struct This avoids allocating and freeing a new context for every file that is being hashed. Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index eb05acb3e..eb5000b64 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -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)