Blame SOURCES/0003-Make-the-default-signature-method-and-the-minimal-ha.patch

0719f5
From f095ac8f5740b6eee687cac97840bc7e72992999 Mon Sep 17 00:00:00 2001
0719f5
From: Jakub Hrozek <jhrozek@redhat.com>
0719f5
Date: Mon, 7 Jun 2021 12:27:15 +0200
0719f5
Subject: [PATCH 3/7] Make the default signature method and the minimal hash
0719f5
 strength configurable (#54037)
0719f5
0719f5
Adds two new configure options:
0719f5
    --with-default-sign-algo
0719f5
    --min-hash-algo
0719f5
0719f5
--with-default-sign-algo sets the default signing algorithm and defaults
0719f5
to rsa-sha1. At the moment, two algorithms are supported: rsa-sha1 and
0719f5
rsa-sha256.
0719f5
0719f5
--min-hash-algo sets the minimum hash algorithm to be accepted. The
0719f5
default is sha1 for backwards compatibility as well.
0719f5
0719f5
Related:
0719f5
https://dev.entrouvert.org/issues/54037
0719f5
---
0719f5
 configure.ac         | 42 +++++++++++++++++++++++++++++
0719f5
 lasso/id-ff/server.c |  2 +-
0719f5
 lasso/id-ff/server.h |  2 ++
0719f5
 lasso/lasso.c        | 51 +++++++++++++++++++++++++++++++++++
0719f5
 lasso/xml/tools.c    | 63 +++++++++++++++++++++++++++++++++++---------
0719f5
 lasso/xml/xml.c      | 24 +++++++++++++++++
0719f5
 lasso/xml/xml.h      |  9 +++++++
0719f5
 tests/random_tests.c |  6 ++---
0719f5
 8 files changed, 182 insertions(+), 17 deletions(-)
0719f5
0719f5
diff --git a/configure.ac b/configure.ac
0719f5
index b527def43..2cdfbb149 100644
0719f5
--- a/configure.ac
0719f5
+++ b/configure.ac
0719f5
@@ -795,6 +795,43 @@ else
0719f5
     AC_MSG_RESULT(no)
0719f5
 fi 
0719f5
 
0719f5
+AC_ARG_WITH([default-sign-algo],
0719f5
+            [AS_HELP_STRING([--with-default-sign-algo=[rsa-sha1|rsa-sha256]],
0719f5
+                            [Default signing algorithm (rsa-sha1)]
0719f5
+                           )
0719f5
+            ]
0719f5
+)
0719f5
+
0719f5
+SIGNING_ALGO=rsa-sha1
0719f5
+if test x"$with_default_sign_algo" != x; then
0719f5
+    if test ! "$with_default_sign_algo" = "rsa-sha1" -a ! "$with_default_sign_algo" = "rsa-sha256"; then
0719f5
+	AC_MSG_ERROR("Default signing algorithm must be either rsa-sha1 or rsa-sha256")
0719f5
+    else
0719f5
+	SIGNING_ALGO=$with_default_sign_algo
0719f5
+    fi
0719f5
+fi
0719f5
+
0719f5
+AC_DEFINE_UNQUOTED(DEFAULT_SIGNING_ALGO, "$SIGNING_ALGO", ["The default signing algorithm"])
0719f5
+
0719f5
+AC_ARG_WITH([min-hash-algo],
0719f5
+            [AS_HELP_STRING([--with-min-hash-algo=[sha1|sha256|sha384|sha512]],
0719f5
+                            [Minimal allowed hash algorithm (rsa-sha1)]
0719f5
+                           )
0719f5
+            ]
0719f5
+)
0719f5
+
0719f5
+MIN_HASH_ALGO=sha1
0719f5
+if test x"$with_min_hash_algo" != x; then
0719f5
+    if test ! "$with_min_hash_algo" = "sha1" -a ! "$with_min_hash_algo" = "sha256" -a ! "$with_min_hash_algo" = "sha384" -a ! "$with_min_hash_algo" = "sha512"; then
0719f5
+	AC_MSG_ERROR("Minimal allowed hash algorithm must be one of sha1, sha256, sha384 or sha512)
0719f5
+    else
0719f5
+	MIN_HASH_ALGO=$with_min_hash_algo
0719f5
+    fi
0719f5
+fi
0719f5
+
0719f5
+AC_DEFINE_UNQUOTED(MIN_HASH_ALGO, "$MIN_HASH_ALGO", ["The minimal hash algorithm"])
0719f5
+
0719f5
+
0719f5
 dnl ==========================================================================
0719f5
 dnl Pedantic compilation
0719f5
 dnl ==========================================================================
0719f5
@@ -939,4 +976,9 @@ Python binding:         ${enable_python}
0719f5
 
0719f5
 C API references:       ${enable_gtk_doc}
0719f5
 Tests suite:            ${enable_tests}
0719f5
+
0719f5
+Crypto settings
0719f5
+---------------
0719f5
+Default signature:      ${SIGNING_ALGO}
0719f5
+Minimal accepted hash:  ${MIN_HASH_ALGO}
0719f5
 )
0719f5
diff --git a/lasso/id-ff/server.c b/lasso/id-ff/server.c
0719f5
index 08bbde833..2bf5b7a8c 100644
0719f5
--- a/lasso/id-ff/server.c
0719f5
+++ b/lasso/id-ff/server.c
0719f5
@@ -682,7 +682,7 @@ instance_init(LassoServer *server)
0719f5
 	server->private_key = NULL;
0719f5
 	server->private_key_password = NULL;
0719f5
 	server->certificate = NULL;
0719f5
-	server->signature_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
0719f5
+	server->signature_method = lasso_get_default_signature_method();
0719f5
 
0719f5
 	server->services = g_hash_table_new_full(g_str_hash, g_str_equal,
0719f5
 			(GDestroyNotify)g_free,
0719f5
diff --git a/lasso/id-ff/server.h b/lasso/id-ff/server.h
0719f5
index 8b4192793..5f9022e9d 100644
0719f5
--- a/lasso/id-ff/server.h
0719f5
+++ b/lasso/id-ff/server.h
0719f5
@@ -133,6 +133,8 @@ LASSO_EXPORT gchar *lasso_server_get_endpoint_url_by_id(const LassoServer *serve
0719f5
 LASSO_EXPORT GList *lasso_server_get_filtered_provider_list(const LassoServer *server,
0719f5
 	LassoProviderRole role, LassoMdProtocolType protocol_type, LassoHttpMethod http_method);
0719f5
 
0719f5
+LASSO_EXPORT LassoSignatureMethod lasso_get_default_signature_method();
0719f5
+void lasso_set_default_signature_method(LassoSignatureMethod meth);
0719f5
 
0719f5
 #ifdef __cplusplus
0719f5
 }
0719f5
diff --git a/lasso/lasso.c b/lasso/lasso.c
0719f5
index 087485998..67340317d 100644
0719f5
--- a/lasso/lasso.c
0719f5
+++ b/lasso/lasso.c
0719f5
@@ -149,6 +149,44 @@ lasso_xmlsec_errors_callback(const char *file G_GNUC_UNUSED, int line G_GNUC_UNU
0719f5
 	g_log("libxmlsec", G_LOG_LEVEL_DEBUG, "libxmlsec: %s:%d:%s:%s:%s:%s:%s", file, line, func, errorObject, errorSubject, xmlSecErrorsGetMsg(reason), msg);
0719f5
 }
0719f5
 
0719f5
+static int
0719f5
+set_default_signature_method()
0719f5
+{
0719f5
+	int rv = LASSO_ERROR_UNDEFINED;
0719f5
+
0719f5
+	if (lasso_strisequal(DEFAULT_SIGNING_ALGO, "rsa-sha256")) {
0719f5
+		lasso_set_default_signature_method(LASSO_SIGNATURE_METHOD_RSA_SHA256);
0719f5
+		rv = 0;
0719f5
+	} else if (lasso_strisequal(DEFAULT_SIGNING_ALGO, "rsa-sha1")) {
0719f5
+		lasso_set_default_signature_method(LASSO_SIGNATURE_METHOD_RSA_SHA1);
0719f5
+		rv = 0;
0719f5
+	}
0719f5
+
0719f5
+	return rv;
0719f5
+}
0719f5
+
0719f5
+static int
0719f5
+set_min_allowed_hash_algo()
0719f5
+{
0719f5
+	int rv = LASSO_ERROR_UNDEFINED;
0719f5
+
0719f5
+	if (lasso_strisequal(MIN_HASH_ALGO, "sha1")) {
0719f5
+		lasso_set_min_signature_method(LASSO_SIGNATURE_METHOD_RSA_SHA1);
0719f5
+		rv = 0;
0719f5
+	} else if (lasso_strisequal(MIN_HASH_ALGO, "sha256")) {
0719f5
+		lasso_set_min_signature_method(LASSO_SIGNATURE_METHOD_RSA_SHA256);
0719f5
+		rv = 0;
0719f5
+	} else if (lasso_strisequal(MIN_HASH_ALGO, "sha384")) {
0719f5
+		lasso_set_min_signature_method(LASSO_SIGNATURE_METHOD_RSA_SHA384);
0719f5
+		rv = 0;
0719f5
+	} else if (lasso_strisequal(MIN_HASH_ALGO, "sha512")) {
0719f5
+		lasso_set_min_signature_method(LASSO_SIGNATURE_METHOD_RSA_SHA512);
0719f5
+		rv = 0;
0719f5
+	}
0719f5
+
0719f5
+	return rv;
0719f5
+}
0719f5
+
0719f5
 /**
0719f5
  * lasso_init:
0719f5
  *
0719f5
@@ -164,6 +202,19 @@ int lasso_init()
0719f5
 	g_type_init();
0719f5
 #endif
0719f5
 
0719f5
+	/* Set the default hash algo */
0719f5
+	if (set_default_signature_method() != 0) {
0719f5
+		message(G_LOG_LEVEL_CRITICAL, "Unsupported signature "
0719f5
+			"algorithm "DEFAULT_SIGNING_ALGO" configured");
0719f5
+		return LASSO_ERROR_UNDEFINED;
0719f5
+	}
0719f5
+	if (set_min_allowed_hash_algo() != 0) {
0719f5
+		message(G_LOG_LEVEL_CRITICAL, "Unsupported hash algorithm "
0719f5
+			"algorithm "MIN_HASH_ALGO" configured");
0719f5
+		return LASSO_ERROR_UNDEFINED;
0719f5
+	}
0719f5
+
0719f5
+
0719f5
 	/* Init Lasso classes */
0719f5
 	for (i=0; functions[i]; i++)
0719f5
 		functions[i]();
0719f5
diff --git a/lasso/xml/tools.c b/lasso/xml/tools.c
0719f5
index 290fd55f2..ce322ee1f 100644
0719f5
--- a/lasso/xml/tools.c
0719f5
+++ b/lasso/xml/tools.c
0719f5
@@ -1505,16 +1505,6 @@ lasso_saml_constrain_dsigctxt(xmlSecDSigCtxPtr dsigCtx) {
0719f5
 			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformExclC14NWithCommentsId) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformInclC14N11Id) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformInclC14N11WithCommentsId) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformSha1Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformHmacSha1Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformDsaSha1Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformRsaSha1Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformSha256Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformHmacSha256Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformRsaSha256Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformSha384Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformHmacSha384Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformRsaSha384Id) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformSha512Id) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformHmacSha512Id) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformRsaSha512Id) < 0)
0719f5
@@ -1523,15 +1513,62 @@ lasso_saml_constrain_dsigctxt(xmlSecDSigCtxPtr dsigCtx) {
0719f5
 		message(G_LOG_LEVEL_CRITICAL, "Error: failed to limit allowed signature transforms");
0719f5
 		return FALSE;
0719f5
 	}
0719f5
+
0719f5
+	if (lasso_get_min_signature_method() <= LASSO_SIGNATURE_METHOD_RSA_SHA384) {
0719f5
+		if ((xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformSha384Id) < 0) ||
0719f5
+			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformHmacSha384Id) < 0) ||
0719f5
+			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformRsaSha384Id) < 0)) {
0719f5
+
0719f5
+			message(G_LOG_LEVEL_CRITICAL, "Error: failed to limit allowed sha384 signature transforms");
0719f5
+			return FALSE;
0719f5
+		}
0719f5
+
0719f5
+		if (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformSha384Id) < 0) {
0719f5
+
0719f5
+			message(G_LOG_LEVEL_CRITICAL, "Error: failed to limit allowed sha384 reference transforms");
0719f5
+			return FALSE;
0719f5
+		}
0719f5
+	}
0719f5
+
0719f5
+	if (lasso_get_min_signature_method() <= LASSO_SIGNATURE_METHOD_RSA_SHA256) {
0719f5
+		if ((xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformSha256Id) < 0) ||
0719f5
+			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformHmacSha256Id) < 0) ||
0719f5
+			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformRsaSha256Id) < 0)) {
0719f5
+
0719f5
+			message(G_LOG_LEVEL_CRITICAL, "Error: failed to limit allowed sha256 signature transforms");
0719f5
+			return FALSE;
0719f5
+		}
0719f5
+
0719f5
+		if (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformSha256Id) < 0) {
0719f5
+
0719f5
+			message(G_LOG_LEVEL_CRITICAL, "Error: failed to limit allowed sha256 reference transforms");
0719f5
+			return FALSE;
0719f5
+		}
0719f5
+	}
0719f5
+
0719f5
+	if (lasso_get_min_signature_method() <= LASSO_SIGNATURE_METHOD_RSA_SHA1) {
0719f5
+		if ((xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformSha1Id) < 0) ||
0719f5
+			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformHmacSha1Id) < 0) ||
0719f5
+			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformDsaSha1Id) < 0) ||
0719f5
+			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformRsaSha1Id) < 0)) {
0719f5
+
0719f5
+			message(G_LOG_LEVEL_CRITICAL, "Error: failed to limit allowed sha1 signature transforms");
0719f5
+			return FALSE;
0719f5
+		}
0719f5
+
0719f5
+		if (xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformSha1Id) < 0) {
0719f5
+
0719f5
+			message(G_LOG_LEVEL_CRITICAL, "Error: failed to limit allowed sha1 reference transforms");
0719f5
+			return FALSE;
0719f5
+		}
0719f5
+	}
0719f5
+
0719f5
 	if((xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformInclC14NId) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformExclC14NId) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformInclC14NWithCommentsId) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformExclC14NWithCommentsId) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformInclC14N11Id) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableSignatureTransform(dsigCtx, xmlSecTransformInclC14N11WithCommentsId) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformSha1Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformSha256Id) < 0) ||
0719f5
-			(xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformSha384Id) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformSha512Id) < 0) ||
0719f5
 			(xmlSecDSigCtxEnableReferenceTransform(dsigCtx, xmlSecTransformEnvelopedId) < 0)) {
0719f5
 
0719f5
diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c
0719f5
index 938844baf..f017ebbe3 100644
0719f5
--- a/lasso/xml/xml.c
0719f5
+++ b/lasso/xml/xml.c
0719f5
@@ -91,6 +91,10 @@ GHashTable *dst_services_by_prefix = NULL; /* ID-WSF 1 extra DST services, index
0719f5
 GHashTable *idwsf2_dst_services_by_href = NULL; /* ID-WSF 2 DST services, indexed on href */
0719f5
 GHashTable *idwsf2_dst_services_by_prefix = NULL; /* ID-WSF 2 DST services, indexed on prefix */
0719f5
 
0719f5
+
0719f5
+static LassoSignatureMethod default_signature_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
0719f5
+static LassoSignatureMethod min_signature_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
0719f5
+
0719f5
 /*****************************************************************************/
0719f5
 /* global methods                                                            */
0719f5
 /*****************************************************************************/
0719f5
@@ -3689,3 +3693,23 @@ lasso_node_new_from_saml2_query(const char *url_or_qs, const char *param_name, L
0719f5
 cleanup:
0719f5
 	return result;
0719f5
 }
0719f5
+
0719f5
+LassoSignatureMethod
0719f5
+lasso_get_default_signature_method() {
0719f5
+	return default_signature_method;
0719f5
+}
0719f5
+
0719f5
+void
0719f5
+lasso_set_default_signature_method(LassoSignatureMethod meth) {
0719f5
+	default_signature_method = meth;
0719f5
+}
0719f5
+
0719f5
+LassoSignatureMethod
0719f5
+lasso_get_min_signature_method() {
0719f5
+	return min_signature_method;
0719f5
+}
0719f5
+
0719f5
+void
0719f5
+lasso_set_min_signature_method(LassoSignatureMethod meth) {
0719f5
+	min_signature_method = meth;
0719f5
+}
0719f5
diff --git a/lasso/xml/xml.h b/lasso/xml/xml.h
0719f5
index 7660a0647..d0d3e1b0d 100644
0719f5
--- a/lasso/xml/xml.h
0719f5
+++ b/lasso/xml/xml.h
0719f5
@@ -116,6 +116,15 @@ typedef enum {
0719f5
 	LASSO_SIGNATURE_METHOD_LAST
0719f5
 } LassoSignatureMethod;
0719f5
 
0719f5
+/* signature method and hash strength */
0719f5
+LassoSignatureMethod lasso_get_default_signature_method();
0719f5
+
0719f5
+void lasso_set_default_signature_method(LassoSignatureMethod meth);
0719f5
+
0719f5
+LassoSignatureMethod lasso_get_min_signature_method();
0719f5
+
0719f5
+void lasso_set_min_signature_method(LassoSignatureMethod meth);
0719f5
+
0719f5
 static inline gboolean
0719f5
 lasso_validate_signature_method(LassoSignatureMethod signature_method)
0719f5
 {
0719f5
diff --git a/tests/random_tests.c b/tests/random_tests.c
0719f5
index fa0367a3c..cf112c7e2 100644
0719f5
--- a/tests/random_tests.c
0719f5
+++ b/tests/random_tests.c
0719f5
@@ -97,7 +97,7 @@ START_TEST(test01_server_new)
0719f5
 	fail_unless(server->private_key != NULL);
0719f5
 	fail_unless(server->private_key_password == NULL);
0719f5
 	fail_unless(server->certificate != NULL);
0719f5
-	fail_unless(server->signature_method == LASSO_SIGNATURE_METHOD_RSA_SHA1);
0719f5
+	fail_unless(server->signature_method == lasso_get_default_signature_method());
0719f5
 	fail_unless(provider->ProviderID != NULL);
0719f5
 	fail_unless(provider->role == 0);
0719f5
 	fail_unless(g_file_get_contents(TESTSDATADIR "/idp1-la/metadata.xml", &content, &len, NULL));
0719f5
@@ -115,7 +115,7 @@ START_TEST(test01_server_new)
0719f5
 	fail_unless(server->private_key != NULL);
0719f5
 	fail_unless(server->private_key_password == NULL);
0719f5
 	fail_unless(server->certificate != NULL);
0719f5
-	fail_unless(server->signature_method == LASSO_SIGNATURE_METHOD_RSA_SHA1);
0719f5
+	fail_unless(server->signature_method == lasso_get_default_signature_method());
0719f5
 	fail_unless(server->providers != NULL);
0719f5
 	fail_unless(provider->ProviderID != NULL);
0719f5
 	fail_unless(provider->role == 0, "provider->role != 0 => provider :=  %d", provider->role);
0719f5
@@ -143,7 +143,7 @@ START_TEST(test02_server_add_provider)
0719f5
 	fail_unless(server->private_key != NULL);
0719f5
 	fail_unless(! server->private_key_password);
0719f5
 	fail_unless(server->certificate != NULL);
0719f5
-	fail_unless(server->signature_method == LASSO_SIGNATURE_METHOD_RSA_SHA1);
0719f5
+	fail_unless(server->signature_method == lasso_get_default_signature_method());
0719f5
 	fail_unless(server->providers != NULL);
0719f5
 	lasso_server_add_provider(
0719f5
 			server,
0719f5
-- 
0719f5
2.26.3
0719f5