glib2/gnutls-hmac.patch
DistroBaker c9c2962400 Merged update from upstream sources
This is an automated DistroBaker update from upstream sources.
If you do not know what this is about or would like to opt out,
contact the OSCI team.

Source: https://src.fedoraproject.org/rpms/glib2.git#646c601be33d0890fb6339d30f904477cdced45a
2021-02-06 22:14:41 +00:00

670 lines
18 KiB
Diff

From 12e9cd51eb0ef07c3554cd035f92d8b7b5b82304 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Fri, 7 Jun 2019 18:44:43 +0000
Subject: [PATCH 1/2] ghmac: Split off wrapper functions into ghmac-utils.c
Prep for adding a GnuTLS HMAC implementation; these are just
utility functions that call the "core" API.
---
glib/ghmac-utils.c | 145 +++++++++++++++++++++++++++++++++++++++++++++
glib/ghmac.c | 112 ----------------------------------
glib/meson.build | 1 +
3 files changed, 146 insertions(+), 112 deletions(-)
create mode 100644 glib/ghmac-utils.c
diff --git a/glib/ghmac-utils.c b/glib/ghmac-utils.c
new file mode 100644
index 000000000..a17359ff1
--- /dev/null
+++ b/glib/ghmac-utils.c
@@ -0,0 +1,145 @@
+/* ghmac.h - data hashing functions
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "ghmac.h"
+
+#include "glib/galloca.h"
+#include "gatomic.h"
+#include "gslice.h"
+#include "gmem.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gtypes.h"
+#include "glibintl.h"
+
+/**
+ * g_compute_hmac_for_data:
+ * @digest_type: a #GChecksumType to use for the HMAC
+ * @key: (array length=key_len): the key to use in the HMAC
+ * @key_len: the length of the key
+ * @data: (array length=length): binary blob to compute the HMAC of
+ * @length: length of @data
+ *
+ * Computes the HMAC for a binary @data of @length. This is a
+ * convenience wrapper for g_hmac_new(), g_hmac_get_string()
+ * and g_hmac_unref().
+ *
+ * The hexadecimal string returned will be in lower case.
+ *
+ * Returns: the HMAC of the binary data as a string in hexadecimal.
+ * The returned string should be freed with g_free() when done using it.
+ *
+ * Since: 2.30
+ */
+gchar *
+g_compute_hmac_for_data (GChecksumType digest_type,
+ const guchar *key,
+ gsize key_len,
+ const guchar *data,
+ gsize length)
+{
+ GHmac *hmac;
+ gchar *retval;
+
+ g_return_val_if_fail (length == 0 || data != NULL, NULL);
+
+ hmac = g_hmac_new (digest_type, key, key_len);
+ if (!hmac)
+ return NULL;
+
+ g_hmac_update (hmac, data, length);
+ retval = g_strdup (g_hmac_get_string (hmac));
+ g_hmac_unref (hmac);
+
+ return retval;
+}
+
+/**
+ * g_compute_hmac_for_bytes:
+ * @digest_type: a #GChecksumType to use for the HMAC
+ * @key: the key to use in the HMAC
+ * @data: binary blob to compute the HMAC of
+ *
+ * Computes the HMAC for a binary @data. This is a
+ * convenience wrapper for g_hmac_new(), g_hmac_get_string()
+ * and g_hmac_unref().
+ *
+ * The hexadecimal string returned will be in lower case.
+ *
+ * Returns: the HMAC of the binary data as a string in hexadecimal.
+ * The returned string should be freed with g_free() when done using it.
+ *
+ * Since: 2.50
+ */
+gchar *
+g_compute_hmac_for_bytes (GChecksumType digest_type,
+ GBytes *key,
+ GBytes *data)
+{
+ gconstpointer byte_data;
+ gsize length;
+ gconstpointer key_data;
+ gsize key_len;
+
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ byte_data = g_bytes_get_data (data, &length);
+ key_data = g_bytes_get_data (key, &key_len);
+ return g_compute_hmac_for_data (digest_type, key_data, key_len, byte_data, length);
+}
+
+
+/**
+ * g_compute_hmac_for_string:
+ * @digest_type: a #GChecksumType to use for the HMAC
+ * @key: (array length=key_len): the key to use in the HMAC
+ * @key_len: the length of the key
+ * @str: the string to compute the HMAC for
+ * @length: the length of the string, or -1 if the string is nul-terminated
+ *
+ * Computes the HMAC for a string.
+ *
+ * The hexadecimal string returned will be in lower case.
+ *
+ * Returns: the HMAC as a hexadecimal string.
+ * The returned string should be freed with g_free()
+ * when done using it.
+ *
+ * Since: 2.30
+ */
+gchar *
+g_compute_hmac_for_string (GChecksumType digest_type,
+ const guchar *key,
+ gsize key_len,
+ const gchar *str,
+ gssize length)
+{
+ g_return_val_if_fail (length == 0 || str != NULL, NULL);
+
+ if (length < 0)
+ length = strlen (str);
+
+ return g_compute_hmac_for_data (digest_type, key, key_len,
+ (const guchar *) str, length);
+}
diff --git a/glib/ghmac.c b/glib/ghmac.c
index 49fd272f0..4f181f21f 100644
--- a/glib/ghmac.c
+++ b/glib/ghmac.c
@@ -329,115 +329,3 @@ g_hmac_get_digest (GHmac *hmac,
g_checksum_update (hmac->digesto, buffer, len);
g_checksum_get_digest (hmac->digesto, buffer, digest_len);
}
-
-/**
- * g_compute_hmac_for_data:
- * @digest_type: a #GChecksumType to use for the HMAC
- * @key: (array length=key_len): the key to use in the HMAC
- * @key_len: the length of the key
- * @data: (array length=length): binary blob to compute the HMAC of
- * @length: length of @data
- *
- * Computes the HMAC for a binary @data of @length. This is a
- * convenience wrapper for g_hmac_new(), g_hmac_get_string()
- * and g_hmac_unref().
- *
- * The hexadecimal string returned will be in lower case.
- *
- * Returns: the HMAC of the binary data as a string in hexadecimal.
- * The returned string should be freed with g_free() when done using it.
- *
- * Since: 2.30
- */
-gchar *
-g_compute_hmac_for_data (GChecksumType digest_type,
- const guchar *key,
- gsize key_len,
- const guchar *data,
- gsize length)
-{
- GHmac *hmac;
- gchar *retval;
-
- g_return_val_if_fail (length == 0 || data != NULL, NULL);
-
- hmac = g_hmac_new (digest_type, key, key_len);
- if (!hmac)
- return NULL;
-
- g_hmac_update (hmac, data, length);
- retval = g_strdup (g_hmac_get_string (hmac));
- g_hmac_unref (hmac);
-
- return retval;
-}
-
-/**
- * g_compute_hmac_for_bytes:
- * @digest_type: a #GChecksumType to use for the HMAC
- * @key: the key to use in the HMAC
- * @data: binary blob to compute the HMAC of
- *
- * Computes the HMAC for a binary @data. This is a
- * convenience wrapper for g_hmac_new(), g_hmac_get_string()
- * and g_hmac_unref().
- *
- * The hexadecimal string returned will be in lower case.
- *
- * Returns: the HMAC of the binary data as a string in hexadecimal.
- * The returned string should be freed with g_free() when done using it.
- *
- * Since: 2.50
- */
-gchar *
-g_compute_hmac_for_bytes (GChecksumType digest_type,
- GBytes *key,
- GBytes *data)
-{
- gconstpointer byte_data;
- gsize length;
- gconstpointer key_data;
- gsize key_len;
-
- g_return_val_if_fail (data != NULL, NULL);
- g_return_val_if_fail (key != NULL, NULL);
-
- byte_data = g_bytes_get_data (data, &length);
- key_data = g_bytes_get_data (key, &key_len);
- return g_compute_hmac_for_data (digest_type, key_data, key_len, byte_data, length);
-}
-
-
-/**
- * g_compute_hmac_for_string:
- * @digest_type: a #GChecksumType to use for the HMAC
- * @key: (array length=key_len): the key to use in the HMAC
- * @key_len: the length of the key
- * @str: the string to compute the HMAC for
- * @length: the length of the string, or -1 if the string is nul-terminated
- *
- * Computes the HMAC for a string.
- *
- * The hexadecimal string returned will be in lower case.
- *
- * Returns: the HMAC as a hexadecimal string.
- * The returned string should be freed with g_free()
- * when done using it.
- *
- * Since: 2.30
- */
-gchar *
-g_compute_hmac_for_string (GChecksumType digest_type,
- const guchar *key,
- gsize key_len,
- const gchar *str,
- gssize length)
-{
- g_return_val_if_fail (length == 0 || str != NULL, NULL);
-
- if (length < 0)
- length = strlen (str);
-
- return g_compute_hmac_for_data (digest_type, key, key_len,
- (const guchar *) str, length);
-}
diff --git a/glib/meson.build b/glib/meson.build
index 8c18e6de4..329b8d197 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -253,6 +253,7 @@ glib_sources = files(
'ggettext.c',
'ghash.c',
'ghmac.c',
+ 'ghmac-utils.c',
'ghook.c',
'ghostutils.c',
'giochannel.c',
--
2.29.2
From 231ed985074af4a354405cf1961fabf9c60bce43 Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Fri, 7 Jun 2019 19:36:54 +0000
Subject: [PATCH 2/2] Add a gnutls backend for GHmac
For RHEL we want apps to use FIPS-certified crypto libraries,
and HMAC apparently counts as "keyed" and hence needs to
be validated.
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1630260
Replaces: https://gitlab.gnome.org/GNOME/glib/merge_requests/897
This is a build-time option that backs the GHmac API with GnuTLS.
Most distributors ship glib-networking built with GnuTLS, and
most apps use glib-networking, so this isn't a net-new library
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.
---
glib/gchecksum.c | 9 ++-
glib/gchecksumprivate.h | 32 ++++++++
glib/ghmac-gnutls.c | 164 ++++++++++++++++++++++++++++++++++++++++
glib/ghmac.c | 3 +
glib/meson.build | 10 ++-
meson.build | 7 ++
meson_options.txt | 5 ++
7 files changed, 224 insertions(+), 6 deletions(-)
create mode 100644 glib/gchecksumprivate.h
create mode 100644 glib/ghmac-gnutls.c
diff --git a/glib/gchecksum.c b/glib/gchecksum.c
index 29b479bc6..929958c3a 100644
--- a/glib/gchecksum.c
+++ b/glib/gchecksum.c
@@ -20,7 +20,7 @@
#include <string.h>
-#include "gchecksum.h"
+#include "gchecksumprivate.h"
#include "gslice.h"
#include "gmem.h"
@@ -173,9 +173,9 @@ sha_byte_reverse (guint32 *buffer,
}
#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */
-static gchar *
-digest_to_string (guint8 *digest,
- gsize digest_len)
+gchar *
+gchecksum_digest_to_string (guint8 *digest,
+ gsize digest_len)
{
gsize i, len = digest_len * 2;
gchar *retval;
@@ -194,6 +194,7 @@ digest_to_string (guint8 *digest,
return retval;
}
+#define digest_to_string gchecksum_digest_to_string
/*
* MD5 Checksum
diff --git a/glib/gchecksumprivate.h b/glib/gchecksumprivate.h
new file mode 100644
index 000000000..86c7a3b61
--- /dev/null
+++ b/glib/gchecksumprivate.h
@@ -0,0 +1,32 @@
+/* gstdioprivate.h - Private GLib stdio functions
+ *
+ * Copyright 2017 Руслан Ижбулатов
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __G_CHECKSUMPRIVATE_H__
+#define __G_CHECKSUMPRIVATE_H__
+
+#include "gchecksum.h"
+
+G_BEGIN_DECLS
+
+gchar *
+gchecksum_digest_to_string (guint8 *digest,
+ gsize digest_len);
+
+G_END_DECLS
+
+#endif
\ No newline at end of file
diff --git a/glib/ghmac-gnutls.c b/glib/ghmac-gnutls.c
new file mode 100644
index 000000000..f1a74a849
--- /dev/null
+++ b/glib/ghmac-gnutls.c
@@ -0,0 +1,164 @@
+/* ghmac.h - data hashing functions
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gnutls/crypto.h>
+
+#include "ghmac.h"
+
+#include "glib/galloca.h"
+#include "gatomic.h"
+#include "gslice.h"
+#include "gmem.h"
+#include "gstrfuncs.h"
+#include "gchecksumprivate.h"
+#include "gtestutils.h"
+#include "gtypes.h"
+#include "glibintl.h"
+
+#ifndef HAVE_GNUTLS
+#error "build configuration error"
+#endif
+
+struct _GHmac
+{
+ int ref_count;
+ GChecksumType digest_type;
+ gnutls_hmac_hd_t hmac;
+ gchar *digest_str;
+};
+
+GHmac *
+g_hmac_new (GChecksumType digest_type,
+ const guchar *key,
+ gsize key_len)
+{
+ gnutls_mac_algorithm_t algo;
+ GHmac *hmac = g_slice_new0 (GHmac);
+ hmac->ref_count = 1;
+ hmac->digest_type = digest_type;
+
+ switch (digest_type)
+ {
+ case G_CHECKSUM_MD5:
+ algo = GNUTLS_MAC_MD5;
+ break;
+ case G_CHECKSUM_SHA1:
+ algo = GNUTLS_MAC_SHA1;
+ break;
+ case G_CHECKSUM_SHA256:
+ algo = GNUTLS_MAC_SHA256;
+ break;
+ case G_CHECKSUM_SHA384:
+ algo = GNUTLS_MAC_SHA384;
+ break;
+ case G_CHECKSUM_SHA512:
+ algo = GNUTLS_MAC_SHA512;
+ break;
+ default:
+ g_return_val_if_reached (NULL);
+ }
+
+ gnutls_hmac_init (&hmac->hmac, algo, key, key_len);
+
+ return hmac;
+}
+
+GHmac *
+g_hmac_copy (const GHmac *hmac)
+{
+ GHmac *copy;
+
+ g_return_val_if_fail (hmac != NULL, NULL);
+
+ copy = g_slice_new0 (GHmac);
+ copy->ref_count = 1;
+ copy->digest_type = hmac->digest_type;
+ copy->hmac = gnutls_hmac_copy (hmac->hmac);
+
+ return copy;
+}
+
+GHmac *
+g_hmac_ref (GHmac *hmac)
+{
+ g_return_val_if_fail (hmac != NULL, NULL);
+
+ g_atomic_int_inc (&hmac->ref_count);
+
+ return hmac;
+}
+
+void
+g_hmac_unref (GHmac *hmac)
+{
+ g_return_if_fail (hmac != NULL);
+
+ if (g_atomic_int_dec_and_test (&hmac->ref_count))
+ {
+ gnutls_hmac_deinit (hmac->hmac, NULL);
+ g_free (hmac->digest_str);
+ g_slice_free (GHmac, hmac);
+ }
+}
+
+
+void
+g_hmac_update (GHmac *hmac,
+ const guchar *data,
+ gssize length)
+{
+ g_return_if_fail (hmac != NULL);
+ g_return_if_fail (length == 0 || data != NULL);
+
+ gnutls_hmac (hmac->hmac, data, length);
+}
+
+const gchar *
+g_hmac_get_string (GHmac *hmac)
+{
+ guint8 *buffer;
+ gsize digest_len;
+
+ g_return_val_if_fail (hmac != NULL, NULL);
+
+ if (hmac->digest_str)
+ return hmac->digest_str;
+
+ digest_len = g_checksum_type_get_length (hmac->digest_type);
+ buffer = g_alloca (digest_len);
+
+ gnutls_hmac_output (hmac->hmac, buffer);
+ hmac->digest_str = gchecksum_digest_to_string (buffer, digest_len);
+ return hmac->digest_str;
+}
+
+
+void
+g_hmac_get_digest (GHmac *hmac,
+ guint8 *buffer,
+ gsize *digest_len)
+{
+ g_return_if_fail (hmac != NULL);
+
+ gnutls_hmac_output (hmac->hmac, buffer);
+ *digest_len = g_checksum_type_get_length (hmac->digest_type);
+}
diff --git a/glib/ghmac.c b/glib/ghmac.c
index 4f181f21f..c62d9ce4e 100644
--- a/glib/ghmac.c
+++ b/glib/ghmac.c
@@ -33,6 +33,9 @@
#include "gtypes.h"
#include "glibintl.h"
+#ifdef HAVE_GNUTLS
+#error "build configuration error"
+#endif
/**
* SECTION:hmac
diff --git a/glib/meson.build b/glib/meson.build
index 329b8d197..2942a7e9b 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -252,7 +252,6 @@ glib_sources = files(
'gfileutils.c',
'ggettext.c',
'ghash.c',
- 'ghmac.c',
'ghmac-utils.c',
'ghook.c',
'ghostutils.c',
@@ -308,6 +307,7 @@ glib_sources = files(
'guriprivate.h',
'gutils.c',
'gutilsprivate.h',
+ 'gchecksumprivate.h',
'guuid.c',
'gvariant.c',
'gvariant-core.c',
@@ -352,6 +352,12 @@ else
glib_dtrace_hdr = []
endif
+if get_option('gnutls')
+ glib_sources += files('ghmac-gnutls.c')
+else
+ glib_sources += files('ghmac.c')
+endif
+
pcre_static_args = []
if use_pcre_static_flag
@@ -378,7 +384,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 + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep],
+ dependencies : pcre_deps + libgnutls_dep + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep],
c_args : glib_c_args,
objc_args : glib_c_args,
)
diff --git a/meson.build b/meson.build
index 0d892fb2d..091029fea 100644
--- a/meson.build
+++ b/meson.build
@@ -2078,6 +2078,13 @@ if host_system == 'linux'
glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found())
endif
+# gnutls is used optionally by ghmac
+libgnutls_dep = []
+if get_option('gnutls')
+ libgnutls_dep = [dependency('gnutls', version : '>=3.6.9', required : true)]
+ glib_conf.set('HAVE_GNUTLS', 1)
+endif
+
if host_system == 'windows'
winsock2 = cc.find_library('ws2_32')
endif
diff --git a/meson_options.txt b/meson_options.txt
index 072765361..d2370042f 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -34,6 +34,11 @@ option('libmount',
value : 'auto',
description : 'build with libmount support')
+option('gnutls',
+ type : 'boolean',
+ value : false,
+ description : 'build with gnutls support')
+
option('internal_pcre',
type : 'boolean',
value : false,
--
2.29.2