Update GHmac patchset and reenable glib2-static

Resolves: #1971823
This commit is contained in:
Michael Catanzaro 2021-06-23 08:56:04 -05:00
parent 20c29ebd2e
commit 2480730783
2 changed files with 464 additions and 49 deletions

View File

@ -1,17 +1,16 @@
Name: glib2 Name: glib2
Version: 2.68.2 Version: 2.68.2
Release: 1%{?dist} Release: 2%{?dist}
Summary: A library of handy utility functions Summary: A library of handy utility functions
License: LGPLv2+ License: LGPLv2+
URL: http://www.gtk.org URL: http://www.gtk.org
Source0: http://download.gnome.org/sources/glib/2.68/glib-%{version}.tar.xz Source0: http://download.gnome.org/sources/glib/2.68/glib-%{version}.tar.xz
%if 0%{?rhel} # Required for RHEL core crypto components policy. Good for Fedora too.
# Required for RHEL core crypto components policy. # https://bugzilla.redhat.com/show_bug.cgi?id=1630260
# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/903 # https://gitlab.gnome.org/GNOME/glib/-/merge_requests/903
Patch0: gnutls-hmac.patch Patch0: gnutls-hmac.patch
%endif
# Add patches to move applications into systemd scopes in compliance with # Add patches to move applications into systemd scopes in compliance with
# https://systemd.io/DESKTOP_ENVIRONMENTS/ # https://systemd.io/DESKTOP_ENVIRONMENTS/
@ -31,10 +30,6 @@ BuildRequires: libselinux-devel
BuildRequires: meson BuildRequires: meson
# for sys/sdt.h # for sys/sdt.h
BuildRequires: systemtap-sdt-devel BuildRequires: systemtap-sdt-devel
%if 0%{?rhel}
# For gnutls-hmac.patch
BuildRequires: pkgconfig(gnutls)
%endif
BuildRequires: pkgconfig(libelf) BuildRequires: pkgconfig(libelf)
BuildRequires: pkgconfig(libffi) BuildRequires: pkgconfig(libffi)
BuildRequires: pkgconfig(libpcre) BuildRequires: pkgconfig(libpcre)
@ -43,6 +38,15 @@ BuildRequires: pkgconfig(sysprof-capture-4)
BuildRequires: pkgconfig(zlib) BuildRequires: pkgconfig(zlib)
BuildRequires: python3-devel BuildRequires: python3-devel
# For gnutls-hmac.patch. We now dlopen libgnutls.so.30 so that we can build a
# static glib2 without depending on a static build of GnuTLS as well. This will
# ensure we notice if the GnuTLS soname bumps, so that we can update our patch.
%if 0%{?__isa_bits} == 64
Requires: libgnutls.so.30()(64bit)
%else
Requires: libgnutls.so.30
%endif
# for GIO content-type support # for GIO content-type support
Recommends: shared-mime-info Recommends: shared-mime-info
@ -79,14 +83,12 @@ BuildArch: noarch
%description doc %description doc
The glib2-doc package includes documentation for the GLib library. The glib2-doc package includes documentation for the GLib library.
%if !0%{?rhel}
%package static %package static
Summary: glib static Summary: glib static
Requires: %{name}-devel = %{version}-%{release} Requires: %{name}-devel = %{version}-%{release}
%description static %description static
The %{name}-static subpackage contains static libraries for %{name}. The %{name}-static subpackage contains static libraries for %{name}.
%endif
%package tests %package tests
Summary: Tests for the glib2 package Summary: Tests for the glib2 package
@ -114,12 +116,8 @@ rm glib/pcre/*.[ch]
-Dglib_debug=disabled \ -Dglib_debug=disabled \
-Dgtk_doc=true \ -Dgtk_doc=true \
-Dinstalled_tests=true \ -Dinstalled_tests=true \
%if 0%{?rhel}
-Dgnutls=true \ -Dgnutls=true \
%endif
%if !0%{?rhel}
--default-library=both \ --default-library=both \
%endif
%{nil} %{nil}
%meson_build %meson_build
@ -229,20 +227,22 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%files doc %files doc
%{_datadir}/gtk-doc/ %{_datadir}/gtk-doc/
%if !0%{?rhel}
%files static %files static
%{_libdir}/libgio-2.0.a %{_libdir}/libgio-2.0.a
%{_libdir}/libglib-2.0.a %{_libdir}/libglib-2.0.a
%{_libdir}/libgmodule-2.0.a %{_libdir}/libgmodule-2.0.a
%{_libdir}/libgobject-2.0.a %{_libdir}/libgobject-2.0.a
%{_libdir}/libgthread-2.0.a %{_libdir}/libgthread-2.0.a
%endif
%files tests %files tests
%{_libexecdir}/installed-tests %{_libexecdir}/installed-tests
%{_datadir}/installed-tests %{_datadir}/installed-tests
%changelog %changelog
* Wed Jun 23 2021 Michael Catanzaro <mcatanzaro@redhat.com> - 2.68.2-2
- Update GHmac patchset and reenable glib2-static
- Resolves: #1971823
* Wed May 19 2021 Michael Catanzaro <mcatanzaro@redhat.com> - 2.68.2-1 * Wed May 19 2021 Michael Catanzaro <mcatanzaro@redhat.com> - 2.68.2-1
- Update to 2.68.2 - Update to 2.68.2
- Resolves: #1961039 - Resolves: #1961039

View File

@ -1,7 +1,7 @@
From 12e9cd51eb0ef07c3554cd035f92d8b7b5b82304 Mon Sep 17 00:00:00 2001 From 86412ea2265ae018ba6146d525cafce78782c0fc Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org> From: Colin Walters <walters@verbum.org>
Date: Fri, 7 Jun 2019 18:44:43 +0000 Date: Fri, 7 Jun 2019 18:44:43 +0000
Subject: [PATCH 1/2] ghmac: Split off wrapper functions into ghmac-utils.c Subject: [PATCH 1/4] ghmac: Split off wrapper functions into ghmac-utils.c
Prep for adding a GnuTLS HMAC implementation; these are just Prep for adding a GnuTLS HMAC implementation; these are just
utility functions that call the "core" API. utility functions that call the "core" API.
@ -284,10 +284,10 @@ index 49fd272f0..4f181f21f 100644
- (const guchar *) str, length); - (const guchar *) str, length);
-} -}
diff --git a/glib/meson.build b/glib/meson.build diff --git a/glib/meson.build b/glib/meson.build
index 8c18e6de4..329b8d197 100644 index 28bfae200..0a37d19ea 100644
--- a/glib/meson.build --- a/glib/meson.build
+++ b/glib/meson.build +++ b/glib/meson.build
@@ -253,6 +253,7 @@ glib_sources = files( @@ -254,6 +254,7 @@ glib_sources = files(
'ggettext.c', 'ggettext.c',
'ghash.c', 'ghash.c',
'ghmac.c', 'ghmac.c',
@ -296,13 +296,12 @@ index 8c18e6de4..329b8d197 100644
'ghostutils.c', 'ghostutils.c',
'giochannel.c', 'giochannel.c',
-- --
2.29.2 2.31.1
From a5ee9970772e182de1c249ee514e87ef38e08360 Mon Sep 17 00:00:00 2001
From 231ed985074af4a354405cf1961fabf9c60bce43 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org> From: Colin Walters <walters@verbum.org>
Date: Fri, 7 Jun 2019 19:36:54 +0000 Date: Fri, 7 Jun 2019 19:36:54 +0000
Subject: [PATCH 2/2] Add a gnutls backend for GHmac Subject: [PATCH 2/4] Add a gnutls backend for GHmac
For RHEL we want apps to use FIPS-certified crypto libraries, For RHEL we want apps to use FIPS-certified crypto libraries,
and HMAC apparently counts as "keyed" and hence needs to and HMAC apparently counts as "keyed" and hence needs to
@ -316,18 +315,47 @@ Most distributors ship glib-networking built with GnuTLS, and
most apps use glib-networking, so this isn't a net-new library most apps use glib-networking, so this isn't a net-new library
in most cases. in most cases.
mcatanzaro note: I've updated Colin's original patch to implement =======================================================================
g_hmac_copy() using gnutls_hmac_copy(), which didn't exist when Colin
developed this patch. mcatanzaro note:
I've updated Colin's original patch with several enhancements:
Implement g_hmac_copy() using gnutls_hmac_copy(), which didn't exist
when Colin developed this patch.
Removed use of GSlice
Better error checking in g_hmac_new(). It is possible for
gnutls_hmac_init() to fail if running in FIPS mode and an MD5 digest is
requested. In this case, we should return NULL rather than returning a
broken GHmac with a NULL gnutls_hmac_hd_t. This was leading to a later
null pointer dereference inside gnutls_hmac_update(). Applications are
responsible for checking to ensure the return value of g_hmac_new() is
not NULL since it is annotated as nullable. Added documentation to
indicate this possibility.
Properly handle length -1 in g_hmac_update(). This means we've been
given a NUL-terminated string and should use strlen(). GnuTLS doesn't
accept -1, so let's call strlen() ourselves.
Crash the application with g_error() if gnutls_hmac() fails for any
reason. This is necessary because g_hmac_update() is not fallible, so we
have no way to indicate error. Crashing seems better than returning the
wrong result later when g_hmac_get_string() or g_hmac_get_digest() is
later called. (Those functions are also not fallible.) Fortunately, I
don't think this error should actually be hit in practice.
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/903
--- ---
glib/gchecksum.c | 9 ++- glib/gchecksum.c | 9 +-
glib/gchecksumprivate.h | 32 ++++++++ glib/gchecksumprivate.h | 32 +++++++
glib/ghmac-gnutls.c | 164 ++++++++++++++++++++++++++++++++++++++++ glib/ghmac-gnutls.c | 187 ++++++++++++++++++++++++++++++++++++++++
glib/ghmac.c | 3 + glib/ghmac.c | 15 ++++
glib/meson.build | 10 ++- glib/meson.build | 10 ++-
meson.build | 7 ++ meson.build | 7 ++
meson_options.txt | 5 ++ meson_options.txt | 5 ++
7 files changed, 224 insertions(+), 6 deletions(-) 7 files changed, 259 insertions(+), 6 deletions(-)
create mode 100644 glib/gchecksumprivate.h create mode 100644 glib/gchecksumprivate.h
create mode 100644 glib/ghmac-gnutls.c create mode 100644 glib/ghmac-gnutls.c
@ -406,10 +434,10 @@ index 000000000..86c7a3b61
\ No newline at end of file \ No newline at end of file
diff --git a/glib/ghmac-gnutls.c b/glib/ghmac-gnutls.c diff --git a/glib/ghmac-gnutls.c b/glib/ghmac-gnutls.c
new file mode 100644 new file mode 100644
index 000000000..f1a74a849 index 000000000..a55375060
--- /dev/null --- /dev/null
+++ b/glib/ghmac-gnutls.c +++ b/glib/ghmac-gnutls.c
@@ -0,0 +1,164 @@ @@ -0,0 +1,186 @@
+/* ghmac.h - data hashing functions +/* ghmac.h - data hashing functions
+ * + *
+ * Copyright (C) 2011 Collabora Ltd. + * Copyright (C) 2011 Collabora Ltd.
@ -464,7 +492,9 @@ index 000000000..f1a74a849
+ gsize key_len) + gsize key_len)
+{ +{
+ gnutls_mac_algorithm_t algo; + gnutls_mac_algorithm_t algo;
+ GHmac *hmac = g_slice_new0 (GHmac); + GHmac *hmac = g_new0 (GHmac, 1);
+ int ret;
+
+ hmac->ref_count = 1; + hmac->ref_count = 1;
+ hmac->digest_type = digest_type; + hmac->digest_type = digest_type;
+ +
@ -489,7 +519,15 @@ index 000000000..f1a74a849
+ g_return_val_if_reached (NULL); + g_return_val_if_reached (NULL);
+ } + }
+ +
+ gnutls_hmac_init (&hmac->hmac, algo, key, key_len); + ret = gnutls_hmac_init (&hmac->hmac, algo, key, key_len);
+ if (ret != 0)
+ {
+ /* There is no way to report an error here, but one possible cause of
+ * failure is that the requested digest may be disabled by FIPS mode.
+ */
+ g_free (hmac->hmac);
+ return NULL;
+ }
+ +
+ return hmac; + return hmac;
+} +}
@ -501,11 +539,15 @@ index 000000000..f1a74a849
+ +
+ g_return_val_if_fail (hmac != NULL, NULL); + g_return_val_if_fail (hmac != NULL, NULL);
+ +
+ copy = g_slice_new0 (GHmac); + copy = g_new0 (GHmac, 1);
+ copy->ref_count = 1; + copy->ref_count = 1;
+ copy->digest_type = hmac->digest_type; + copy->digest_type = hmac->digest_type;
+ copy->hmac = gnutls_hmac_copy (hmac->hmac); + copy->hmac = gnutls_hmac_copy (hmac->hmac);
+ +
+ /* g_hmac_copy is not allowed to fail, so we'll have to crash on error. */
+ if (!copy->hmac)
+ g_error ("gnutls_hmac_copy failed");
+
+ return copy; + return copy;
+} +}
+ +
@ -528,7 +570,7 @@ index 000000000..f1a74a849
+ { + {
+ gnutls_hmac_deinit (hmac->hmac, NULL); + gnutls_hmac_deinit (hmac->hmac, NULL);
+ g_free (hmac->digest_str); + g_free (hmac->digest_str);
+ g_slice_free (GHmac, hmac); + g_free (hmac);
+ } + }
+} +}
+ +
@ -538,10 +580,18 @@ index 000000000..f1a74a849
+ const guchar *data, + const guchar *data,
+ gssize length) + gssize length)
+{ +{
+ int ret;
+
+ g_return_if_fail (hmac != NULL); + g_return_if_fail (hmac != NULL);
+ g_return_if_fail (length == 0 || data != NULL); + g_return_if_fail (length == 0 || data != NULL);
+ +
+ gnutls_hmac (hmac->hmac, data, length); + if (length == -1)
+ length = strlen ((const char *)data);
+
+ /* g_hmac_update is not allowed to fail, so we'll have to crash on error. */
+ ret = gnutls_hmac (hmac->hmac, data, length);
+ if (ret != 0)
+ g_error ("gnutls_hmac failed: %s", gnutls_strerror (ret));
+} +}
+ +
+const gchar * +const gchar *
@ -575,7 +625,7 @@ index 000000000..f1a74a849
+ *digest_len = g_checksum_type_get_length (hmac->digest_type); + *digest_len = g_checksum_type_get_length (hmac->digest_type);
+} +}
diff --git a/glib/ghmac.c b/glib/ghmac.c diff --git a/glib/ghmac.c b/glib/ghmac.c
index 4f181f21f..c62d9ce4e 100644 index 4f181f21f..0e39ea40a 100644
--- a/glib/ghmac.c --- a/glib/ghmac.c
+++ b/glib/ghmac.c +++ b/glib/ghmac.c
@@ -33,6 +33,9 @@ @@ -33,6 +33,9 @@
@ -588,11 +638,30 @@ index 4f181f21f..c62d9ce4e 100644
/** /**
* SECTION:hmac * SECTION:hmac
@@ -84,6 +87,18 @@ struct _GHmac
* Support for digests of type %G_CHECKSUM_SHA512 has been added in GLib 2.42.
* Support for %G_CHECKSUM_SHA384 was added in GLib 2.52.
*
+ * Note that #GHmac creation may fail, in which case this function will
+ * return %NULL. Since there is no error parameter, it is not possible
+ * to indicate why.
+ *
+ * In Fedora, CentOS Stream, and Red Hat Enterprise Linux, GLib is
+ * configured to use GnuTLS to implement #GHmac in order to support FIPS
+ * compliance. This introduces additional failure possibilities that are
+ * not present in upstream GLib. For example, the creation of a #GHmac
+ * will fail if @digest_type is %G_CHECKSUM_MD5 and the system is
+ * running in FIPS mode. #GHmac creation may also fail if GLib is unable
+ * to load GnuTLS.
+ *
* Returns: the newly created #GHmac, or %NULL.
* Use g_hmac_unref() to free the memory allocated by it.
*
diff --git a/glib/meson.build b/glib/meson.build diff --git a/glib/meson.build b/glib/meson.build
index 329b8d197..2942a7e9b 100644 index 0a37d19ea..b17c89dd9 100644
--- a/glib/meson.build --- a/glib/meson.build
+++ b/glib/meson.build +++ b/glib/meson.build
@@ -252,7 +252,6 @@ glib_sources = files( @@ -253,7 +253,6 @@ glib_sources = files(
'gfileutils.c', 'gfileutils.c',
'ggettext.c', 'ggettext.c',
'ghash.c', 'ghash.c',
@ -600,7 +669,7 @@ index 329b8d197..2942a7e9b 100644
'ghmac-utils.c', 'ghmac-utils.c',
'ghook.c', 'ghook.c',
'ghostutils.c', 'ghostutils.c',
@@ -308,6 +307,7 @@ glib_sources = files( @@ -309,6 +308,7 @@ glib_sources = files(
'guriprivate.h', 'guriprivate.h',
'gutils.c', 'gutils.c',
'gutilsprivate.h', 'gutilsprivate.h',
@ -608,7 +677,7 @@ index 329b8d197..2942a7e9b 100644
'guuid.c', 'guuid.c',
'gvariant.c', 'gvariant.c',
'gvariant-core.c', 'gvariant-core.c',
@@ -352,6 +352,12 @@ else @@ -353,6 +353,12 @@ else
glib_dtrace_hdr = [] glib_dtrace_hdr = []
endif endif
@ -621,7 +690,7 @@ index 329b8d197..2942a7e9b 100644
pcre_static_args = [] pcre_static_args = []
if use_pcre_static_flag if use_pcre_static_flag
@@ -378,7 +384,7 @@ libglib = library('glib-2.0', @@ -379,7 +385,7 @@ libglib = library('glib-2.0',
# intl.lib is not compatible with SAFESEH # intl.lib is not compatible with SAFESEH
link_args : [noseh_link_args, glib_link_flags, win32_ldflags], link_args : [noseh_link_args, glib_link_flags, win32_ldflags],
include_directories : configinc, include_directories : configinc,
@ -631,10 +700,10 @@ index 329b8d197..2942a7e9b 100644
objc_args : glib_c_args, objc_args : glib_c_args,
) )
diff --git a/meson.build b/meson.build diff --git a/meson.build b/meson.build
index 0d892fb2d..091029fea 100644 index a0ee8b774..064dba800 100644
--- a/meson.build --- a/meson.build
+++ b/meson.build +++ b/meson.build
@@ -2078,6 +2078,13 @@ if host_system == 'linux' @@ -2104,6 +2104,13 @@ if host_system == 'linux'
glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found()) glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found())
endif endif
@ -665,5 +734,351 @@ index 072765361..d2370042f 100644
type : 'boolean', type : 'boolean',
value : false, value : false,
-- --
2.29.2 2.31.1
From cde56a63aa12ae7c30f85af7d058fa5e666aa2e9 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@redhat.com>
Date: Wed, 16 Jun 2021 20:35:00 -0500
Subject: [PATCH 3/4] dlopen GnuTLS instead of linking directly
I'd like to enable our GnuTLS GHmac patchset in Fedora in order to
ensure it is receiving sufficient real-world testing, since we've
discovered several bugs thus far. Problem is Fedora has one requirement
that RHEL does not: it needs to build glib as a static lib. This is
needed by QEMU in Fedora for complicated technical reasons that I don't
understand. However, nothing in RHEL needs it. This means we failed to
notice that glib2-static is broken in RHEL, because there is no
gnutls-static! We could fix this by adding a gnutls-static package, but
that seems like overkill, and adding more static libraries where they're
not truly necessary is not the direction we want to move in anyway. So
instead, let's just dlopen GnuTLS to sidestep this problem entirely.
This would not be a good solution for upstream, but upstream has made
clear that this patchset is already non-upstreamable, so it will be fine
for our purposes.
---
glib/ghmac-gnutls.c | 101 ++++++++++++++++++++++++++++++++++++++++++--
glib/ghmac.c | 2 +-
glib/meson.build | 2 +-
meson.build | 6 +--
4 files changed, 102 insertions(+), 9 deletions(-)
diff --git a/glib/ghmac-gnutls.c b/glib/ghmac-gnutls.c
index a55375060..0469d2bd0 100644
--- a/glib/ghmac-gnutls.c
+++ b/glib/ghmac-gnutls.c
@@ -19,8 +19,8 @@
#include "config.h"
+#include <dlfcn.h>
#include <string.h>
-#include <gnutls/crypto.h>
#include "ghmac.h"
@@ -31,13 +31,16 @@
#include "gstrfuncs.h"
#include "gchecksumprivate.h"
#include "gtestutils.h"
+#include "gthread.h"
#include "gtypes.h"
#include "glibintl.h"
-#ifndef HAVE_GNUTLS
+#ifndef USE_GNUTLS
#error "build configuration error"
#endif
+typedef gpointer gnutls_hmac_hd_t;
+
struct _GHmac
{
int ref_count;
@@ -46,15 +49,107 @@ struct _GHmac
gchar *digest_str;
};
+typedef enum
+{
+ GNUTLS_MAC_MD5 = 2,
+ GNUTLS_MAC_SHA1 = 3,
+ GNUTLS_MAC_SHA256 = 6,
+ GNUTLS_MAC_SHA384 = 7,
+ GNUTLS_MAC_SHA512 = 8,
+} gnutls_mac_algorithm_t;
+
+/* Why are we dlopening GnuTLS instead of linking to it directly? Because we
+ * want to be able to build GLib as a static library without depending on a
+ * static build of GnuTLS. QEMU depends on static linking with GLib, but Fedora
+ * does not ship a static build of GnuTLS, and this allows us to avoid changing
+ * that.
+ */
+static int (*gnutls_hmac_init) (gnutls_hmac_hd_t *dig, gnutls_mac_algorithm_t algorithm, const void *key, size_t keylen);
+static gnutls_hmac_hd_t (*gnutls_hmac_copy) (gnutls_hmac_hd_t handle);
+static void (*gnutls_hmac_deinit) (gnutls_hmac_hd_t handle, void *digest);
+static int (*gnutls_hmac) (gnutls_hmac_hd_t handle, const void *ptext, size_t ptext_len);
+static void (*gnutls_hmac_output) (gnutls_hmac_hd_t handle, void *digest);
+static const char * (*gnutls_strerror) (int error);
+
+static gsize gnutls_initialize_attempted = 0;
+static gboolean gnutls_initialize_successful = FALSE;
+
+static void
+initialize_gnutls (void)
+{
+ gpointer libgnutls;
+
+ libgnutls = dlopen ("libgnutls.so.30", RTLD_LAZY | RTLD_GLOBAL);
+ if (!libgnutls)
+ {
+ g_warning ("Cannot use GHmac: failed to load libgnutls.so.30: %s", dlerror ());
+ return;
+ }
+
+ gnutls_hmac_init = dlsym (libgnutls, "gnutls_hmac_init");
+ if (!gnutls_hmac_init)
+ {
+ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_init: %s", dlerror ());
+ return;
+ }
+
+ gnutls_hmac_copy = dlsym (libgnutls, "gnutls_hmac_copy");
+ if (!gnutls_hmac_copy)
+ {
+ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_copy: %s", dlerror ());
+ return;
+ }
+
+ gnutls_hmac_deinit = dlsym (libgnutls, "gnutls_hmac_deinit");
+ if (!gnutls_hmac_deinit)
+ {
+ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_deinit: %s", dlerror ());
+ return;
+ }
+
+ gnutls_hmac = dlsym (libgnutls, "gnutls_hmac");
+ if (!gnutls_hmac)
+ {
+ g_warning ("Cannot use GHmac: failed to load gnutls_hmac: %s", dlerror ());
+ return;
+ }
+
+ gnutls_hmac_output = dlsym (libgnutls, "gnutls_hmac_output");
+ if (!gnutls_hmac_output)
+ {
+ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_output: %s", dlerror ());
+ return;
+ }
+
+ gnutls_strerror = dlsym (libgnutls, "gnutls_strerror");
+ if (!gnutls_strerror)
+ {
+ g_warning ("Cannot use GHmac: failed to load gnutls_strerror: %s", dlerror ());
+ return;
+ }
+
+ gnutls_initialize_successful = TRUE;
+}
+
GHmac *
g_hmac_new (GChecksumType digest_type,
const guchar *key,
gsize key_len)
{
gnutls_mac_algorithm_t algo;
- GHmac *hmac = g_new0 (GHmac, 1);
+ GHmac *hmac;
int ret;
+ if (g_once_init_enter (&gnutls_initialize_attempted))
+ {
+ initialize_gnutls ();
+ g_once_init_leave (&gnutls_initialize_attempted, 1);
+ }
+
+ if (!gnutls_initialize_successful)
+ return NULL;
+
+ hmac = g_new0 (GHmac, 1);
hmac->ref_count = 1;
hmac->digest_type = digest_type;
diff --git a/glib/ghmac.c b/glib/ghmac.c
index 0e39ea40a..2d9be91b8 100644
--- a/glib/ghmac.c
+++ b/glib/ghmac.c
@@ -33,7 +33,7 @@
#include "gtypes.h"
#include "glibintl.h"
-#ifdef HAVE_GNUTLS
+#ifdef USE_GNUTLS
#error "build configuration error"
#endif
diff --git a/glib/meson.build b/glib/meson.build
index b17c89dd9..a015f7755 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -385,7 +385,7 @@ libglib = library('glib-2.0',
# intl.lib is not compatible with SAFESEH
link_args : [noseh_link_args, glib_link_flags, win32_ldflags],
include_directories : configinc,
- dependencies : pcre_deps + libgnutls_dep + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep],
+ dependencies : pcre_deps + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep] + [libdl_dep],
c_args : glib_c_args,
objc_args : glib_c_args,
)
diff --git a/meson.build b/meson.build
index 064dba800..7aae7dfea 100644
--- a/meson.build
+++ b/meson.build
@@ -2104,11 +2104,9 @@ if host_system == 'linux'
glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found())
endif
-# gnutls is used optionally by ghmac
-libgnutls_dep = []
+# gnutls is used optionally by GHmac
if get_option('gnutls')
- libgnutls_dep = [dependency('gnutls', version : '>=3.6.9', required : true)]
- glib_conf.set('HAVE_GNUTLS', 1)
+ glib_conf.set('USE_GNUTLS', 1)
endif
if host_system == 'windows'
--
2.31.1
From b61ea19037287cae2e6152e9616767a691bf4af0 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@redhat.com>
Date: Wed, 16 Jun 2021 20:46:24 -0500
Subject: [PATCH 4/4] Add test for GHmac in FIPS mode
This will test a few problems that we hit recently:
g_hmac_copy() is broken, https://bugzilla.redhat.com/show_bug.cgi?id=1786538
Crash in g_hmac_update() in FIPS mode, https://bugzilla.redhat.com/show_bug.cgi?id=1971533
Crash when passing -1 length to g_hmac_update() (discovered in #1971533)
We'll also test to ensure MD5 fails, and stop compiling the other MD5
tests.
---
glib/tests/hmac.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/glib/tests/hmac.c b/glib/tests/hmac.c
index 3ac3206df..6698c4d19 100644
--- a/glib/tests/hmac.c
+++ b/glib/tests/hmac.c
@@ -1,7 +1,10 @@
+#include "config.h"
+
#include <glib.h>
#include <string.h>
#include <stdlib.h>
+#ifndef USE_GNUTLS
/* HMAC-MD5 test vectors as per RFC 2202 */
/* Test 1 */
@@ -81,6 +84,7 @@ guint8 key_md5_test7[] = {
guint8 result_md5_test7[] = {
0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, 0x1f, 0xb1,
0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e };
+#endif
/* HMAC-SHA1, HMAC-SHA256, HMAC-SHA384 and HMAC-SHA512 test vectors
* as per RFCs 2202 and 4868.
@@ -299,6 +303,7 @@ typedef struct {
gconstpointer result;
} HmacCase;
+#ifndef USE_GNUTLS
HmacCase hmac_md5_tests[] = {
{ G_CHECKSUM_MD5, key_md5_test1, 16, "Hi There", 8, result_md5_test1 },
{ G_CHECKSUM_MD5, "Jefe", 4, "what do ya want for nothing?", 28,
@@ -317,6 +322,7 @@ HmacCase hmac_md5_tests[] = {
73, result_md5_test7 },
{ -1, NULL, 0, NULL, 0, NULL },
};
+#endif
HmacCase hmac_sha1_tests[] = {
{ G_CHECKSUM_SHA1, key_sha_test1, 20, "Hi There", 8, result_sha1_test1 },
@@ -493,11 +499,44 @@ test_hmac_for_bytes (void)
g_bytes_unref (data);
}
+#ifdef USE_GNUTLS
+static void
+test_gnutls_fips_mode (void)
+{
+ GHmac *hmac;
+ GHmac *copy;
+
+ /* No MD5 in FIPS mode. */
+ hmac = g_hmac_new (G_CHECKSUM_MD5, "abc123", sizeof ("abc123"));
+ g_assert_null (hmac);
+
+ /* SHA-256 should be good. */
+ hmac = g_hmac_new (G_CHECKSUM_SHA256, "abc123", sizeof ("abc123"));
+ g_assert_nonnull (hmac);
+
+ /* Ensure g_hmac_update() does not crash when called with -1. */
+ g_hmac_update (hmac, "You win again, gravity!", -1);
+
+ /* Ensure g_hmac_copy() does not crash. */
+ copy = g_hmac_copy (hmac);
+ g_assert_nonnull (hmac);
+ g_hmac_unref (hmac);
+
+ g_assert_cmpstr (g_hmac_get_string (copy), ==, "795ba6900bcb22e8ce65c2ec02db4e85697da921deb960ee3143bf88a4a60f83");
+ g_hmac_unref (copy);
+}
+#endif
+
int
main (int argc,
char **argv)
{
int i;
+
+#ifdef USE_GNUTLS
+ g_setenv ("GNUTLS_FORCE_FIPS_MODE", "1", FALSE);
+#endif
+
g_test_init (&argc, &argv, NULL);
for (i = 0 ; hmac_sha1_tests[i].key_len > 0 ; i++)
@@ -532,6 +571,7 @@ main (int argc,
g_free (name);
}
+#ifndef USE_GNUTLS
for (i = 0 ; hmac_md5_tests[i].key_len > 0 ; i++)
{
gchar *name = g_strdup_printf ("/hmac/md5-%d", i + 1);
@@ -539,6 +579,7 @@ main (int argc,
(void (*)(const void *)) test_hmac);
g_free (name);
}
+#endif
g_test_add_func ("/hmac/ref-unref", test_hmac_ref_unref);
g_test_add_func ("/hmac/copy", test_hmac_copy);
@@ -546,5 +587,9 @@ main (int argc,
g_test_add_func ("/hmac/for-string", test_hmac_for_string);
g_test_add_func ("/hmac/for-bytes", test_hmac_for_bytes);
+#ifdef USE_GNUTLS
+ g_test_add_func ("/hmac/gnutls-fips-mode", test_gnutls_fips_mode);
+#endif
+
return g_test_run ();
}
--
2.31.1