1
0
mirror of https://github.com/systemd/systemd synced 2024-07-09 04:26:06 +00:00

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
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2021-11-02 09:58:04 +01:00
parent 57633d2376
commit 6214d42bd2
4 changed files with 60 additions and 20 deletions

1
TODO
View File

@ -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

View 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)

View 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) {
initialize_libgcrypt(false);
#if PREFER_OPENSSL
j->checksum_ctx = EVP_MD_CTX_new();
if (!j->checksum_ctx)
return log_oom();
if (gcry_md_open(&j->checksum_context, GCRY_MD_SHA256, 0) != 0)
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_ctx, GCRY_MD_SHA256, 0) != 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Failed to initialize hash context.");
#endif
}
return 0;

View 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;