diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-11-02 09:58:04 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-11-30 23:00:21 +0100 |
commit | 6214d42bd26657e6f406b6f7039fbbac14d52369 (patch) | |
tree | ce444dbe351e084387ce741d42c7680764c94578 /src/import | |
parent | 57633d2376233629c73cf580650902ba6d1ada8d (diff) | |
download | systemd-6214d42bd26657e6f406b6f7039fbbac14d52369.tar.gz |
import: port importd from libgcrypt to openssl^gcrypt
This is heavily based on Kevin Kuehler's work, but the logic is also
significantly changed: instead of a straighforward port to openssl, both
versions of the code are kept, and at compile time we pick one or the other.
The code is purposefully kept "dumb" — the idea is that the libgcrypt codepaths
are only temporary and will be removed after everybody upgrades to openssl 3.
Thus, a separate abstraction layer is not introduced. Instead, very simple
ifdefs are used to select one or the other. If we added an abstraction layer,
we'd have to remove it again afterwards, and it don't think it makes sense to
do that for a temporary solution.
Co-authored-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
# Conflicts:
# meson.build
Diffstat (limited to 'src/import')
-rw-r--r-- | src/import/pull-job.c | 65 | ||||
-rw-r--r-- | src/import/pull-job.h | 4 |
2 files changed, 55 insertions, 14 deletions
diff --git a/src/import/pull-job.c b/src/import/pull-job.c index 34b116a8f8..f5eb82131e 100644 --- a/src/import/pull-job.c +++ b/src/import/pull-job.c @@ -41,8 +41,12 @@ PullJob* pull_job_unref(PullJob *j) { import_compress_free(&j->compress); - if (j->checksum_context) - gcry_md_close(j->checksum_context); + if (j->checksum_ctx) +#if PREFER_OPENSSL + EVP_MD_CTX_free(j->checksum_ctx); +#else + gcry_md_close(j->checksum_ctx); +#endif free(j->url); free(j->etag); @@ -102,9 +106,13 @@ static int pull_job_restart(PullJob *j, const char *new_url) { import_compress_free(&j->compress); - if (j->checksum_context) { - gcry_md_close(j->checksum_context); - j->checksum_context = NULL; + if (j->checksum_ctx) { +#if PREFER_OPENSSL + EVP_MD_CTX_free(j->checksum_ctx); +#else + gcry_md_close(j->checksum_ctx); +#endif + j->checksum_ctx = NULL; } r = pull_job_begin(j); @@ -200,16 +208,30 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) { goto finish; } - if (j->checksum_context) { - uint8_t *k; + if (j->checksum_ctx) { + unsigned checksum_len; +#if PREFER_OPENSSL + uint8_t k[EVP_MAX_MD_SIZE]; - k = gcry_md_read(j->checksum_context, GCRY_MD_SHA256); + r = EVP_DigestFinal_ex(j->checksum_ctx, k, &checksum_len); + if (r == 0) { + r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get checksum."); + goto finish; + } + assert(checksum_len <= sizeof k); +#else + const uint8_t *k; + + k = gcry_md_read(j->checksum_ctx, GCRY_MD_SHA256); if (!k) { r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get checksum."); goto finish; } - j->checksum = hexmem(k, gcry_md_get_algo_dlen(GCRY_MD_SHA256)); + checksum_len = gcry_md_get_algo_dlen(GCRY_MD_SHA256); +#endif + + j->checksum = hexmem(k, checksum_len); if (!j->checksum) { r = log_oom(); goto finish; @@ -358,8 +380,16 @@ static int pull_job_write_compressed(PullJob *j, void *p, size_t sz) { return log_error_errno(SYNTHETIC_ERRNO(EFBIG), "Content length incorrect."); - if (j->checksum_context) - gcry_md_write(j->checksum_context, p, sz); + if (j->checksum_ctx) { +#if PREFER_OPENSSL + r = EVP_DigestUpdate(j->checksum_ctx, p, sz); + if (r == 0) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Could not hash chunk."); +#else + gcry_md_write(j->checksum_ctx, p, sz); +#endif + } r = import_uncompress(&j->compress, p, sz, pull_job_write_uncompressed, j); if (r < 0) @@ -392,11 +422,22 @@ static int pull_job_open_disk(PullJob *j) { } if (j->calc_checksum) { +#if PREFER_OPENSSL + j->checksum_ctx = EVP_MD_CTX_new(); + if (!j->checksum_ctx) + return log_oom(); + + r = EVP_DigestInit_ex(j->checksum_ctx, EVP_sha256(), NULL); + if (r == 0) + return log_error_errno(SYNTHETIC_ERRNO(EIO), + "Failed to initialize hash context."); +#else initialize_libgcrypt(false); - if (gcry_md_open(&j->checksum_context, GCRY_MD_SHA256, 0) != 0) + if (gcry_md_open(&j->checksum_ctx, GCRY_MD_SHA256, 0) != 0) return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize hash context."); +#endif } return 0; diff --git a/src/import/pull-job.h b/src/import/pull-job.h index bc5258a693..7a98b0f2f6 100644 --- a/src/import/pull-job.h +++ b/src/import/pull-job.h @@ -1,12 +1,12 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -#include <gcrypt.h> #include <sys/stat.h> #include "curl-util.h" #include "import-compress.h" #include "macro.h" +#include "openssl-util.h" #include "pull-common.h" typedef struct PullJob PullJob; @@ -74,7 +74,7 @@ struct PullJob { usec_t last_status_usec; bool calc_checksum; - gcry_md_hd_t checksum_context; + hash_context_t checksum_ctx; char *checksum; bool sync; |