]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
import: port importd from libgcrypt to openssl^gcrypt
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 2 Nov 2021 08:58:04 +0000 (09:58 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 30 Nov 2021 22:00:21 +0000 (23:00 +0100)
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

TODO
meson.build
src/import/pull-job.c
src/import/pull-job.h

diff --git a/TODO b/TODO
index 0047829c51cbe67cb4b281ddc26b91752f20bd39..e710f2c587fb0128b423e7f13d9f7115648caaf9 100644 (file)
--- a/TODO
+++ b/TODO
@@ -437,7 +437,6 @@ Features:
   confusion is gone)
   - port resolved over from libgcrypt (DNSSEC code)
   - port journald + fsprg over from libgcrypt
-  - port importd over from libgcrypt
   - when that's done: kill gnutls support in resolved
 
 * add growvol and makevol options for /etc/crypttab, similar to
index dee05b6017bb9d0b5faecd56122858dfdf9b16cf..5748853121a240985400d3aa2bf6ebcf785bdc99 100644 (file)
@@ -1538,9 +1538,9 @@ lib_openssl_or_gcrypt = conf.get('PREFER_OPENSSL') == 1 ? libopenssl : libgcrypt
 want_importd = get_option('importd')
 if want_importd != 'false'
         have = (conf.get('HAVE_LIBCURL') == 1 and
+                conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1 and
                 conf.get('HAVE_ZLIB') == 1 and
-                conf.get('HAVE_XZ') == 1 and
-                conf.get('HAVE_GCRYPT') == 1)
+                conf.get('HAVE_XZ') == 1)
         if want_importd == 'true' and not have
                 error('importd support was requested, but dependencies are not available')
         endif
@@ -2729,10 +2729,10 @@ if conf.get('ENABLE_IMPORTD') == 1
                 link_with : [libshared],
                 dependencies : [versiondep,
                                 libcurl,
+                                lib_openssl_or_gcrypt,
                                 libz,
                                 libbzip2,
-                                libxz,
-                                libgcrypt],
+                                libxz],
                 install_rpath : rootlibexecdir,
                 install : true,
                 install_dir : rootlibexecdir)
index 34b116a8f87946e4f1e3aafe7387a6cc801e4793..f5eb82131e4bd7b99772afc10a5fbd4b0539826d 100644 (file)
@@ -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;
index bc5258a6934cd83bfdb862761bc7cbfac21f8fb8..7a98b0f2f652e8ab97c01acccb28e3de74b9cb37 100644 (file)
@@ -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;