From 7e8facb36b218720bfd9326c4b668acc5da56cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 27 Oct 2021 15:39:48 +0200 Subject: [PATCH] port string_hashsum from libgcrypt to openssl^gcrypt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows resolved and importd to be built without libgcrypt. Note that we now say either 'cryptographic library' or 'cryptolib'. Co-authored-by: Zbigniew Jędrzejewski-Szmek --- TODO | 4 +-- meson.build | 24 +++++++-------- src/basic/build.c | 2 +- src/basic/gcrypt-util.c | 2 ++ src/basic/gcrypt-util.h | 19 +++++++----- src/resolve/resolvectl.c | 1 + src/resolve/resolved-conf.c | 6 ++-- src/resolve/resolved-dns-packet.c | 6 ++-- src/resolve/resolved-link.c | 4 +-- src/shared/openssl-util.c | 30 +++++++++++++++++++ src/shared/openssl-util.h | 12 ++++++++ src/test/meson.build | 6 ++-- .../{test-gcrypt-util.c => test-cryptolib.c} | 17 ++++++++--- 13 files changed, 96 insertions(+), 37 deletions(-) rename src/test/{test-gcrypt-util.c => test-cryptolib.c} (54%) diff --git a/TODO b/TODO index e710f2c587f..6757836e684 100644 --- a/TODO +++ b/TODO @@ -433,9 +433,7 @@ Features: * socket units: allow creating a udev monitor socket with ListenDevices= or so, with matches, then activate app through that passing socket over -* unify on openssl (as soon as OpenSSL 3.0 is out, and the Debian license - confusion is gone) - - port resolved over from libgcrypt (DNSSEC code) +* unify on openssl: - port journald + fsprg over from libgcrypt - when that's done: kill gnutls support in resolved diff --git a/meson.build b/meson.build index b4a3b865c17..968d752fded 100644 --- a/meson.build +++ b/meson.build @@ -1448,18 +1448,6 @@ else endif conf.set10('HAVE_DBUS', have) -default_dnssec = get_option('default-dnssec') -if skip_deps - default_dnssec = 'no' -endif -if default_dnssec != 'no' and conf.get('HAVE_GCRYPT') == 0 - message('default-dnssec cannot be set to yes or allow-downgrade when gcrypt is disabled. Setting default-dnssec to no.') - default_dnssec = 'no' -endif -conf.set('DEFAULT_DNSSEC_MODE', - 'DNSSEC_' + default_dnssec.underscorify().to_upper()) -conf.set_quoted('DEFAULT_DNSSEC_MODE_STR', default_dnssec) - dns_over_tls = get_option('dns-over-tls') if dns_over_tls != 'false' if dns_over_tls == 'openssl' @@ -1535,6 +1523,18 @@ conf.set10('HAVE_OPENSSL_OR_GCRYPT', conf.get('HAVE_OPENSSL') == 1 or conf.get('HAVE_GCRYPT') == 1) lib_openssl_or_gcrypt = conf.get('PREFER_OPENSSL') == 1 ? libopenssl : libgcrypt +default_dnssec = get_option('default-dnssec') +if skip_deps + default_dnssec = 'no' +endif +if default_dnssec != 'no' and conf.get('HAVE_OPENSSL_OR_GCRYPT') == 0 + message('default-dnssec cannot be set to yes or allow-downgrade openssl and gcrypt are disabled. Setting default-dnssec to no.') + default_dnssec = 'no' +endif +conf.set('DEFAULT_DNSSEC_MODE', + 'DNSSEC_' + default_dnssec.underscorify().to_upper()) +conf.set_quoted('DEFAULT_DNSSEC_MODE_STR', default_dnssec) + want_importd = get_option('importd') if want_importd != 'false' have = (conf.get('HAVE_LIBCURL') == 1 and diff --git a/src/basic/build.c b/src/basic/build.c index 45074591a64..f8baaabb9fa 100644 --- a/src/basic/build.c +++ b/src/basic/build.c @@ -48,7 +48,7 @@ const char* const systemd_features = " -SECCOMP" #endif - /* crypto libraries */ + /* cryptographic libraries */ #if HAVE_GCRYPT " +GCRYPT" diff --git a/src/basic/gcrypt-util.c b/src/basic/gcrypt-util.c index cdc308aca33..64c63cdab1f 100644 --- a/src/basic/gcrypt-util.c +++ b/src/basic/gcrypt-util.c @@ -18,6 +18,7 @@ void initialize_libgcrypt(bool secmem) { gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); } +# if !PREFER_OPENSSL int string_hashsum(const char *s, size_t len, int md_algorithm, char **out) { _cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL; gcry_error_t err; @@ -47,4 +48,5 @@ int string_hashsum(const char *s, size_t len, int md_algorithm, char **out) { *out = enc; return 0; } +# endif #endif diff --git a/src/basic/gcrypt-util.h b/src/basic/gcrypt-util.h index 27dcc72028d..4c40cefbeda 100644 --- a/src/basic/gcrypt-util.h +++ b/src/basic/gcrypt-util.h @@ -12,23 +12,28 @@ #include "macro.h" void initialize_libgcrypt(bool secmem); -int string_hashsum(const char *s, size_t len, int md_algorithm, char **out); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(gcry_md_hd_t, gcry_md_close, NULL); #endif +#if !PREFER_OPENSSL +# if HAVE_GCRYPT +int string_hashsum(const char *s, size_t len, int md_algorithm, char **out); +# endif + static inline int string_hashsum_sha224(const char *s, size_t len, char **out) { -#if HAVE_GCRYPT +# if HAVE_GCRYPT return string_hashsum(s, len, GCRY_MD_SHA224, out); -#else +# else return -EOPNOTSUPP; -#endif +# endif } static inline int string_hashsum_sha256(const char *s, size_t len, char **out) { -#if HAVE_GCRYPT +# if HAVE_GCRYPT return string_hashsum(s, len, GCRY_MD_SHA256, out); -#else +# else return -EOPNOTSUPP; -#endif +# endif } +#endif diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 20455bf7a93..5b3ceeff36a 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -23,6 +23,7 @@ #include "main-func.h" #include "missing_network.h" #include "netlink-util.h" +#include "openssl-util.h" #include "pager.h" #include "parse-argument.h" #include "parse-util.h" diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c index 453f1175e11..a4e44f29bec 100644 --- a/src/resolve/resolved-conf.c +++ b/src/resolve/resolved-conf.c @@ -498,14 +498,14 @@ int manager_parse_config_file(Manager *m) { return r; } -#if ! HAVE_GCRYPT +#if !HAVE_OPENSSL_OR_GCRYPT if (m->dnssec_mode != DNSSEC_NO) { - log_warning("DNSSEC option cannot be enabled or set to allow-downgrade when systemd-resolved is built without gcrypt support. Turning off DNSSEC support."); + log_warning("DNSSEC option cannot be enabled or set to allow-downgrade when systemd-resolved is built without a cryptographic library. Turning off DNSSEC support."); m->dnssec_mode = DNSSEC_NO; } #endif -#if ! ENABLE_DNS_OVER_TLS +#if !ENABLE_DNS_OVER_TLS if (m->dns_over_tls_mode != DNS_OVER_TLS_NO) { log_warning("DNS-over-TLS option cannot be enabled or set to opportunistic when systemd-resolved is built without DNS-over-TLS support. Turning off DNS-over-TLS support."); m->dns_over_tls_mode = DNS_OVER_TLS_NO; diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index a70ec177431..d45f87ff5d1 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #if HAVE_GCRYPT -#include +# include #endif #include "alloc-util.h" @@ -776,7 +776,7 @@ int dns_packet_append_opt( static const uint8_t rfc6975[] = { 0, 5, /* OPTION_CODE: DAU */ -#if HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600 +#if PREFER_OPENSSL || (HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600) 0, 7, /* LIST_LENGTH */ #else 0, 6, /* LIST_LENGTH */ @@ -787,7 +787,7 @@ int dns_packet_append_opt( DNSSEC_ALGORITHM_RSASHA512, DNSSEC_ALGORITHM_ECDSAP256SHA256, DNSSEC_ALGORITHM_ECDSAP384SHA384, -#if HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600 +#if PREFER_OPENSSL || (HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600) DNSSEC_ALGORITHM_ED25519, #endif diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index dd219f297ce..0013cd0b7fb 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -414,9 +414,9 @@ void link_set_dnssec_mode(Link *l, DnssecMode mode) { assert(l); -#if ! HAVE_GCRYPT +#if !HAVE_OPENSSL_OR_GCRYPT if (IN_SET(mode, DNSSEC_YES, DNSSEC_ALLOW_DOWNGRADE)) - log_warning("DNSSEC option for the link cannot be enabled or set to allow-downgrade when systemd-resolved is built without gcrypt support. Turning off DNSSEC support."); + log_warning("DNSSEC option for the link cannot be enabled or set to allow-downgrade when systemd-resolved is built without a cryptographic library. Turning off DNSSEC support."); return; #endif diff --git a/src/shared/openssl-util.c b/src/shared/openssl-util.c index 75fed19f2e2..fdfe4655942 100644 --- a/src/shared/openssl-util.c +++ b/src/shared/openssl-util.c @@ -2,6 +2,7 @@ #include "openssl-util.h" #include "alloc-util.h" +#include "hexdecoct.h" #if HAVE_OPENSSL int openssl_hash(const EVP_MD *alg, @@ -107,4 +108,33 @@ int rsa_pkey_to_suitable_key_size( *ret_suitable_key_size = suitable_key_size; return 0; } + +# if PREFER_OPENSSL +int string_hashsum( + const char *s, + size_t len, + const EVP_MD *md_algorithm, + char **ret) { + + uint8_t hash[EVP_MAX_MD_SIZE]; + size_t hash_size; + char *enc; + int r; + + hash_size = EVP_MD_size(md_algorithm); + assert(hash_size > 0); + + r = openssl_hash(md_algorithm, s, len, hash, NULL); + if (r < 0) + return r; + + enc = hexmem(hash, hash_size); + if (!enc) + return -ENOMEM; + + *ret = enc; + return 0; + +} +# endif #endif diff --git a/src/shared/openssl-util.h b/src/shared/openssl-util.h index 6eaf581195c..d5b18559874 100644 --- a/src/shared/openssl-util.h +++ b/src/shared/openssl-util.h @@ -62,3 +62,15 @@ typedef const char* elliptic_curve_t; typedef gcry_md_hd_t hash_context_t; # define OPENSSL_OR_GCRYPT(a, b) (b) #endif + +#if PREFER_OPENSSL +int string_hashsum(const char *s, size_t len, hash_algorithm_t md_algorithm, char **ret); + +static inline int string_hashsum_sha224(const char *s, size_t len, char **ret) { + return string_hashsum(s, len, EVP_sha224(), ret); +} + +static inline int string_hashsum_sha256(const char *s, size_t len, char **ret) { + return string_hashsum(s, len, EVP_sha256(), ret); +} +#endif diff --git a/src/test/meson.build b/src/test/meson.build index de0b8d7fd22..71d2422caf0 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -594,8 +594,10 @@ tests += [ [['src/test/test-id128.c']], - [['src/test/test-gcrypt-util.c'], - [], [], [], 'HAVE_GCRYPT'], + [['src/test/test-cryptolib.c'], + [libshared], + [lib_openssl_or_gcrypt], + [], 'HAVE_OPENSSL_OR_GCRYPT'], [['src/test/test-nss-hosts.c', 'src/test/nss-test-util.c', diff --git a/src/test/test-gcrypt-util.c b/src/test/test-cryptolib.c similarity index 54% rename from src/test/test-gcrypt-util.c rename to src/test/test-cryptolib.c index 8eb63cd3859..ef39bda6535 100644 --- a/src/test/test-gcrypt-util.c +++ b/src/test/test-cryptolib.c @@ -3,25 +3,34 @@ #include "alloc-util.h" #include "gcrypt-util.h" #include "macro.h" +#include "openssl-util.h" #include "string-util.h" #include "tests.h" TEST(string_hashsum) { _cleanup_free_ char *out1 = NULL, *out2 = NULL, *out3 = NULL, *out4 = NULL; - assert_se(string_hashsum("asdf", 4, GCRY_MD_SHA224, &out1) == 0); + assert_se(string_hashsum("asdf", 4, + OPENSSL_OR_GCRYPT(EVP_sha224(), GCRY_MD_SHA224), + &out1) == 0); /* echo -n 'asdf' | sha224sum - */ assert_se(streq(out1, "7872a74bcbf298a1e77d507cd95d4f8d96131cbbd4cdfc571e776c8a")); - assert_se(string_hashsum("asdf", 4, GCRY_MD_SHA256, &out2) == 0); + assert_se(string_hashsum("asdf", 4, + OPENSSL_OR_GCRYPT(EVP_sha256(), GCRY_MD_SHA256), + &out2) == 0); /* echo -n 'asdf' | sha256sum - */ assert_se(streq(out2, "f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b")); - assert_se(string_hashsum("", 0, GCRY_MD_SHA224, &out3) == 0); + assert_se(string_hashsum("", 0, + OPENSSL_OR_GCRYPT(EVP_sha224(), GCRY_MD_SHA224), + &out3) == 0); /* echo -n '' | sha224sum - */ assert_se(streq(out3, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")); - assert_se(string_hashsum("", 0, GCRY_MD_SHA256, &out4) == 0); + assert_se(string_hashsum("", 0, + OPENSSL_OR_GCRYPT(EVP_sha256(), GCRY_MD_SHA256), + &out4) == 0); /* echo -n '' | sha256sum - */ assert_se(streq(out4, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")); }