File CVE-2025-46784.patch of Package lasso.41555

From 228ac9470f383c5c9dad9f4d314b708c9fd45f16 Mon Sep 17 00:00:00 2001
From: Benjamin Dauvergne <bdauvergne@entrouvert.com>
Date: Wed, 16 Nov 2022 15:36:53 +0100
Subject: [PATCH] Make lasso_inflate output the inflated buffer size (#71399)

---
 lasso/xml/tools.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/lasso/xml/tools.c b/lasso/xml/tools.c
index bc0510c7..cc3d5f2e 100644
--- a/lasso/xml/tools.c
+++ b/lasso/xml/tools.c
@@ -1357,17 +1357,19 @@ lasso_get_query_string_param_value(const char *qs, const char *param_key, const
 }
 
 unsigned char*
-lasso_inflate(unsigned char *input, size_t len)
+lasso_inflate(unsigned char *input, size_t len, size_t *outlen)
 {
 	z_stream zstr;
 	unsigned char *output;
 	int z_err;
 
+	*outlen = 0;
 	zstr.zalloc = NULL;
 	zstr.zfree = NULL;
 	zstr.opaque = NULL;
 
-	output = g_malloc(len*20);
+	// add one to account for the zero byte
+	output = g_malloc(len*20+1);
 	zstr.avail_in = len;
 	zstr.next_in = (unsigned char*)input;
 	zstr.total_in = 0;
@@ -1391,6 +1393,7 @@ lasso_inflate(unsigned char *input, size_t len)
 	}
 	output[zstr.total_out] = 0;
 	inflateEnd(&zstr);
+	*outlen = zstr.total_out;
 
 	return output;
 }
@@ -1400,6 +1403,7 @@ gboolean
 lasso_node_init_from_deflated_query_part(LassoNode *node, char *deflate_string)
 {
 	int len;
+	size_t outlen = 0;
 	xmlChar *b64_zre, *zre, *re;
 	xmlDoc *doc;
 	xmlNode *root;
@@ -1415,13 +1419,13 @@ lasso_node_init_from_deflated_query_part(LassoNode *node, char *deflate_string)
 		return FALSE;
 	}
 
-	re = lasso_inflate(zre, len);
+	re = lasso_inflate(zre, len, &outlen);
 	xmlFree(zre);
 
 	if (! re)
 		return FALSE;
 
-	doc = lasso_xml_parse_memory((char*)re, strlen((char*)re));
+	doc = lasso_xml_parse_memory((char*)re, outlen);
 	lasso_release_string(re);
 
 	root = xmlDocGetRootElement(doc);
@@ -3166,6 +3170,7 @@ lasso_get_saml_message(xmlChar **query_fields) {
 	char *t = NULL;
 	int rc = 0;
 	int len = 0;
+	size_t outlen = 0;
 
 	for (i=0; (field=query_fields[i]); i++) {
 		t = strchr((char*)field, '=');
@@ -3201,7 +3206,7 @@ lasso_get_saml_message(xmlChar **query_fields) {
 		goto cleanup;
 	}
 	/* rc contains the length of the result */
-	saml_message = (char*)lasso_inflate((unsigned char*) decoded_message, rc);
+	saml_message = (char*)lasso_inflate((unsigned char*) decoded_message, rc, &outlen);
 cleanup:
 	if (decoded_message) {
 		lasso_release(decoded_message);

From b263815fa495371adc1bb59045cf0c33fa3fb71a Mon Sep 17 00:00:00 2001
From: Benjamin Dauvergne <bdauvergne@entrouvert.com>
Date: Wed, 16 Nov 2022 13:08:04 +0100
Subject: [PATCH] Add new define LASSO_XMLSEC_VERSION_NUMBER allow version
 check on libxmlsec (#71399)

---
 configure.ac | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/configure.ac b/configure.ac
index adf0be50..6ceb4703 100644
--- a/configure.ac
+++ b/configure.ac
@@ -171,6 +171,10 @@ AC_DEFINE_UNQUOTED(LASSO_VERSION_MAJOR, $VERSION_MAJOR, [Major version number])
 AC_DEFINE_UNQUOTED(LASSO_VERSION_MINOR, $VERSION_MINOR, [Minor version number])
 AC_DEFINE_UNQUOTED(LASSO_VERSION_SUBMINOR, $VERSION_RELEASE, [Release version number])
 
+dnl Create an XMLSEC version number for tests
+AC_DEFINE(LASSO_XMLSEC_VERSION_NUMBER, [(((XMLSEC_VERSION_MAJOR * 0x010000) + (XMLSEC_VERSION_MINOR * 0x0100) + (XMLSEC_VERSION_SUBMINOR * 0x01)))], [XMLSEC Version number])
+AH_BOTTOM([#include <xmlsec/version.h>])
+
 dnl Dirty hack in order to have dynamic resource version numbering.
 WINDOWS_VERSION=`echo $VERSION_MAJOR,$VERSION_MINOR,$VERSION_RELEASE,0`
 AC_SUBST(WINDOWS_VERSION)

From 1aa6271f93e48b24f42991aba8906dfd073a1fe3 Mon Sep 17 00:00:00 2001
From: Benjamin Dauvergne <bdauvergne@entrouvert.com>
Date: Wed, 16 Nov 2022 15:38:35 +0100
Subject: [PATCH] Adapt lasso_base64_decode to the deprecation of
 xmlSecBase64Decode (#71399)

We now use the non-deprecated new API (since xmlsec 1.2.35) xmlSecBase64Decode_ex.
---
 lasso/xml/tools.c | 60 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 45 insertions(+), 15 deletions(-)

diff --git a/lasso/xml/tools.c b/lasso/xml/tools.c
index cc3d5f2e..9b928daa 100644
--- a/lasso/xml/tools.c
+++ b/lasso/xml/tools.c
@@ -70,6 +70,7 @@
 #include <stdarg.h>
 #include <ctype.h>
 #include "../lasso_config.h"
+#include "config.h"
 
 /**
  * SECTION:saml2_utils
@@ -2516,24 +2517,53 @@ cleanup:
 gboolean
 lasso_base64_decode(const char *from, char **buffer, int *buffer_len)
 {
-	size_t len = strlen(from);
-	int ret;
+	int fromlen = 0;
+	xmlChar *out = NULL;
+	xmlSecSize outlen = 0;
+	xmlSecSize decodedlen = 0;
+	int rc = TRUE;
+	int ret = 0;
 
-	/* base64 map 4 bytes to 3 */
-	len = len / 4 + (len % 4 ? 1 : 0);
-	len *= 3;
-	len += 1; /* zero byte */
-	*buffer = g_malloc0(len);
-
-	xmlSecErrorsDefaultCallbackEnableOutput(FALSE);
-	ret = xmlSecBase64Decode(BAD_CAST from, BAD_CAST *buffer, len);
-	xmlSecErrorsDefaultCallbackEnableOutput(TRUE);
-	if (ret <= 0) {
-		lasso_release_string(*buffer);
+	if (! from) {
 		return FALSE;
 	}
-	*buffer_len = ret;
-	return TRUE;
+
+	fromlen = strlen(from);
+
+	/* base64 map 4 bytes to 3 */
+	outlen = fromlen / 4 + (fromlen % 4 ? 1 : 0);
+	outlen *= 3;
+	outlen += 1; /* zero byte */
+	out = g_malloc0(outlen);
+
+#if LASSO_XMLSEC_VERSION_NUMBER >= 0x010223
+	xmlSecErrorsDefaultCallbackEnableOutput(FALSE);
+	ret = xmlSecBase64Decode_ex(BAD_CAST from, out, outlen, &decodedlen);
+	xmlSecErrorsDefaultCallbackEnableOutput(TRUE);
+	if (ret == 0) {
+		out[outlen - 1] = 0;
+		lasso_transfer_string(*buffer, *((char**)&out));
+		*buffer_len = decodedlen;
+	} else {
+		rc = FALSE;
+	}
+#else
+	xmlSecErrorsDefaultCallbackEnableOutput(FALSE);
+	ret = xmlSecBase64Decode(BAD_CAST from, out, outlen);
+	xmlSecErrorsDefaultCallbackEnableOutput(TRUE);
+
+	if (ret >= 0) {
+		out[outlen - 1] = 0;
+		lasso_transfer_string(*buffer, *((char**)&out));
+		*buffer_len = ret;
+	} else {
+		rc = FALSE;
+	}
+#endif
+	if (out) {
+		lasso_release_string(out);
+	}
+	return rc;
 }
 
 /**

From 8a588a8acb4a9cb7c7cb4dfd91a8278264a6d15a Mon Sep 17 00:00:00 2001
From: Benjamin Dauvergne <bdauvergne@entrouvert.com>
Date: Wed, 16 Nov 2022 15:40:19 +0100
Subject: [PATCH] Replace all use of xmlSecBase64Decode by lasso_base64_decode
 (#71399)

---
 lasso/id-ff/login.c      |  12 ++-
 lasso/id-ff/provider.c   |   8 +-
 lasso/id-ff/session.c    |  15 ++--
 lasso/saml-2.0/profile.c |  35 ++++----
 lasso/xml/tools.c        | 176 ++++++++++++++++-----------------------
 lasso/xml/xml.c          |  16 ++--
 6 files changed, 112 insertions(+), 150 deletions(-)

diff --git a/lasso/id-ff/login.c b/lasso/id-ff/login.c
index f1f1bce3..d5559901 100644
--- a/lasso/id-ff/login.c
+++ b/lasso/id-ff/login.c
@@ -1652,7 +1652,8 @@ lasso_login_init_request(LassoLogin *login, gchar *response_msg,
 	int i;
 	char *artifact_b64 = NULL, *provider_succinct_id_b64;
 	char provider_succinct_id[21];
-	char artifact[43];
+	char *artifact = NULL;
+	int artifact_len = 0;
 	LassoSamlpRequestAbstract *request;
 	LassoProfile *profile;
 
@@ -1689,18 +1690,23 @@ lasso_login_init_request(LassoLogin *login, gchar *response_msg,
 		lasso_assign_string(artifact_b64, response_msg);
 	}
 
-	i = xmlSecBase64Decode((xmlChar*)artifact_b64, (xmlChar*)artifact, 43);
-	if (i < 0 || i > 42) {
+	if (! lasso_base64_decode(artifact_b64, &artifact, &artifact_len)) {
+		return LASSO_PROFILE_ERROR_INVALID_ARTIFACT;
+	}
+	if (artifact_len != 42) {
 		lasso_release_string(artifact_b64);
+		lasso_release_string(artifact);
 		return LASSO_PROFILE_ERROR_INVALID_ARTIFACT;
 	}
 
 	if (artifact[0] != 0 || artifact[1] != 3) { /* wrong type code */
 		lasso_release_string(artifact_b64);
+		lasso_release_string(artifact);
 		return LASSO_PROFILE_ERROR_INVALID_ARTIFACT;
 	}
 
 	memcpy(provider_succinct_id, artifact+2, 20);
+	lasso_release_string(artifact);
 	provider_succinct_id[20] = 0;
 
 	provider_succinct_id_b64 = (char*)xmlSecBase64Encode((xmlChar*)provider_succinct_id, 20, 0);
diff --git a/lasso/id-ff/provider.c b/lasso/id-ff/provider.c
index a4b29337..496a961c 100644
--- a/lasso/id-ff/provider.c
+++ b/lasso/id-ff/provider.c
@@ -1434,12 +1434,12 @@ lasso_provider_verify_signature(LassoProvider *provider,
 
 	if (format == LASSO_MESSAGE_FORMAT_BASE64) {
 		int len;
-		char *msg = g_malloc(strlen(message));
-		len = xmlSecBase64Decode((xmlChar*)message, (xmlChar*)msg, strlen(message));
-		if (len < 0) {
+		char *msg = NULL;
+
+		if (! lasso_base64_decode(message, &msg, &len)) {
 			goto_cleanup_with_rc(LASSO_PROFILE_ERROR_INVALID_MSG);
 		}
-		doc = lasso_xml_parse_memory(msg, strlen(msg));
+		doc = lasso_xml_parse_memory(msg, len);
 		lasso_release_string(msg);
 	} else {
 		doc = lasso_xml_parse_memory(message, strlen(message));
diff --git a/lasso/id-ff/session.c b/lasso/id-ff/session.c
index e22a5e80..c303470c 100644
--- a/lasso/id-ff/session.c
+++ b/lasso/id-ff/session.c
@@ -797,25 +797,22 @@ get_xmlNode(LassoNode *node, G_GNUC_UNUSED gboolean lasso_dump)
 
 xmlNode*
 base64_to_xmlNode(xmlChar *buffer) {
-	xmlChar *decoded = NULL;
+	char *decoded = NULL;
+	int decoded_len = 0;
 	xmlDoc *doc = NULL;
 	xmlNode *ret = NULL;
-	int l1,l2;
 
-	l1 = 4*strlen((char*)buffer)+2;
-	decoded = g_malloc(l1);
-	l2 = xmlSecBase64Decode(buffer, decoded, l1);
-	if (l2 < 0)
+	if (! lasso_base64_decode((char*)buffer, &decoded, &decoded_len))
 		goto cleanup;
-	doc = xmlParseMemory((char*)decoded, l2);
+	doc = xmlParseMemory(decoded, decoded_len);
 	if (doc == NULL)
 		goto cleanup;
 	ret = xmlDocGetRootElement(doc);
 	if (ret) {
-	ret = xmlCopyNode(ret, 1);
+		ret = xmlCopyNode(ret, 1);
 	}
 cleanup:
-	lasso_release(decoded);
+	lasso_release_string(decoded);
 	lasso_release_doc(doc);
 
 	return ret;
diff --git a/lasso/saml-2.0/profile.c b/lasso/saml-2.0/profile.c
index 9f2b5156..378f072d 100644
--- a/lasso/saml-2.0/profile.c
+++ b/lasso/saml-2.0/profile.c
@@ -288,7 +288,8 @@ lasso_saml20_profile_init_artifact_resolve(LassoProfile *profile,
 	char *artifact_b64 = NULL;
 	xmlChar *provider_succinct_id_b64 = NULL;
 	char *provider_succinct_id[21];
-	char artifact[45];
+	char *artifact = NULL;
+	int artifact_len = 0;
 	LassoSamlp2RequestAbstract *request = NULL;
 	LassoProvider *remote_provider = NULL;
 	int i = 0;
@@ -307,21 +308,17 @@ lasso_saml20_profile_init_artifact_resolve(LassoProfile *profile,
 			return LASSO_PROFILE_ERROR_MISSING_ARTIFACT;
 		}
 	} else if (method == LASSO_HTTP_METHOD_ARTIFACT_POST) {
-		artifact_b64 = g_strdup(msg);
+		lasso_assign_string(artifact_b64, msg);
 	} else {
 		return critical_error(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
 	}
 
-	i = xmlSecBase64Decode((xmlChar*)artifact_b64, (xmlChar*)artifact, 45);
-	if (i < 0 || i > 44) {
-		lasso_release_string(artifact_b64);
-		return LASSO_PROFILE_ERROR_INVALID_ARTIFACT;
-	}
+	goto_cleanup_if_fail_with_rc(lasso_base64_decode(artifact_b64, &artifact, &artifact_len), LASSO_PROFILE_ERROR_INVALID_ARTIFACT);
 
-	if (artifact[0] != 0 || artifact[1] != 4) { /* wrong type code */
-		lasso_release_string(artifact_b64);
-		return LASSO_PROFILE_ERROR_INVALID_ARTIFACT;
-	}
+	goto_cleanup_if_fail_with_rc(artifact_len == 44, LASSO_PROFILE_ERROR_INVALID_ARTIFACT);
+
+	/* wrong type code */
+	goto_cleanup_if_fail_with_rc(artifact[0] == 0 && artifact[1] == 4, LASSO_PROFILE_ERROR_INVALID_ARTIFACT);
 
 	memcpy(provider_succinct_id, artifact+4, 20);
 	provider_succinct_id[20] = 0;
@@ -330,10 +327,7 @@ lasso_saml20_profile_init_artifact_resolve(LassoProfile *profile,
 
 	lasso_assign_new_string(profile->remote_providerID, lasso_server_get_providerID_from_hash(
 			profile->server, (char*)provider_succinct_id_b64));
-	lasso_release_xml_string(provider_succinct_id_b64);
-	if (profile->remote_providerID == NULL) {
-		return LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND;
-	}
+	goto_cleanup_if_fail_with_rc(profile->remote_providerID, LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
 
 	/* resolve the resolver url using the endpoint index in the artifact string */
 	remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
@@ -342,15 +336,11 @@ lasso_saml20_profile_init_artifact_resolve(LassoProfile *profile,
 			remote_provider_role,
 			LASSO_SAML2_METADATA_ELEMENT_ARTIFACT_RESOLUTION_SERVICE, NULL, FALSE,
 			FALSE, index_endpoint));
-	if (! profile->msg_url) {
-		debug("looking for index endpoint %d", index_endpoint);
-		return LASSO_PROFILE_ERROR_ENDPOINT_INDEX_NOT_FOUND;
-	}
-
+	goto_cleanup_if_fail_with_rc(profile->msg_url, LASSO_PROFILE_ERROR_ENDPOINT_INDEX_NOT_FOUND);
 
 	lasso_assign_new_gobject(profile->request, lasso_samlp2_artifact_resolve_new());
 	request = LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request);
-	lasso_assign_new_string(LASSO_SAMLP2_ARTIFACT_RESOLVE(request)->Artifact, artifact_b64);
+	lasso_transfer_string(LASSO_SAMLP2_ARTIFACT_RESOLVE(request)->Artifact, artifact_b64);
 	request->ID = lasso_build_unique_id(32);
 	lasso_assign_string(request->Version, "2.0");
 	request->Issuer = LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
@@ -361,6 +351,9 @@ lasso_saml20_profile_init_artifact_resolve(LassoProfile *profile,
 				(LassoNode*)request));
 
 cleanup:
+	lasso_release_string(artifact_b64);
+	lasso_release_string(artifact);
+	lasso_release_xml_string(provider_succinct_id_b64);
 	return rc;
 }
 
diff --git a/lasso/xml/tools.c b/lasso/xml/tools.c
index 9b928daa..24f82169 100644
--- a/lasso/xml/tools.c
+++ b/lasso/xml/tools.c
@@ -1403,37 +1403,32 @@ lasso_inflate(unsigned char *input, size_t len, size_t *outlen)
 gboolean
 lasso_node_init_from_deflated_query_part(LassoNode *node, char *deflate_string)
 {
-	int len;
-	size_t outlen = 0;
-	xmlChar *b64_zre, *zre, *re;
-	xmlDoc *doc;
-	xmlNode *root;
+	xmlChar *buffer= NULL;
+	char *decoded = NULL;
+	int decoded_len = 0;
+	xmlChar *re = NULL;
+	size_t re_len = 0;
+	xmlDoc *doc = NULL;
+	xmlNode *root = NULL;
+	gboolean rc = TRUE;
 
-	b64_zre = (xmlChar*)xmlURIUnescapeString(deflate_string, 0, NULL);
-	len = strlen((char*)b64_zre);
-	zre = xmlMalloc(len*4);
-	len = xmlSecBase64Decode(b64_zre, zre, len*4);
-	xmlFree(b64_zre);
-	if (len == -1) {
-		message(G_LOG_LEVEL_CRITICAL, "Failed to base64-decode query");
-		xmlFree(zre);
-		return FALSE;
-	}
+	buffer = (xmlChar*)xmlURIUnescapeString(deflate_string, 0, NULL);
+	goto_cleanup_if_fail_with_rc(lasso_base64_decode((char*)buffer, &decoded, &decoded_len), FALSE);
 
-	re = lasso_inflate(zre, len, &outlen);
-	xmlFree(zre);
+	re = lasso_inflate((unsigned char*)decoded, decoded_len, &re_len);
+	goto_cleanup_if_fail_with_rc_with_warning(re != NULL, FALSE);
 
-	if (! re)
-		return FALSE;
-
-	doc = lasso_xml_parse_memory((char*)re, outlen);
-	lasso_release_string(re);
+	doc = lasso_xml_parse_memory((char*)re, strlen((char*)re));
+	goto_cleanup_if_fail_with_rc_with_warning(doc != NULL, FALSE);
 
 	root = xmlDocGetRootElement(doc);
 	lasso_node_init_from_xml(node, root);
+cleanup:
+	lasso_release_xml_string(buffer);
+	lasso_release_string(decoded);
+	lasso_release_string(re);
 	lasso_release_doc(doc);
-
-	return TRUE;
+	return rc;
 }
 
 char*
@@ -1894,40 +1889,44 @@ lasso_xml_get_soap_content(xmlNode *root)
 LassoMessageFormat
 lasso_xml_parse_message(const char *message, LassoMessageFormat constraint, xmlDoc **doc_out, xmlNode **root_out)
 {
-	char *msg = NULL;
-	gboolean b64 = FALSE;
+	const char *msg = NULL;
+	int msg_len = 0;
+	char *base64_decoded_message = NULL;
 	LassoMessageFormat rc = LASSO_MESSAGE_FORMAT_UNKNOWN;
 	xmlDoc *doc = NULL;
 	xmlNode *root = NULL;
 	gboolean any = constraint == LASSO_MESSAGE_FORMAT_UNKNOWN;
 
-	msg = (char*)message;
-
 	/* BASE64 case */
 	if (any || constraint == LASSO_MESSAGE_FORMAT_BASE64) {
 		if (message[0] != 0 && is_base64(message)) {
-			msg = g_malloc(strlen(message));
-			rc = xmlSecBase64Decode((xmlChar*)message, (xmlChar*)msg, strlen(message));
-			if (rc >= 0) {
-				b64 = TRUE;
-			} else {
-				lasso_release(msg);
-				msg = (char*)message;
+			if (lasso_base64_decode(message, &base64_decoded_message, &msg_len)) {
+				rc = LASSO_MESSAGE_FORMAT_BASE64;
+				msg = base64_decoded_message;
 			}
 		}
 	}
 
+	if (! msg) {
+		msg = message;
+		msg_len = strlen(message);
+	}
+
 	/* XML case */
 	if (any || constraint == LASSO_MESSAGE_FORMAT_BASE64 ||
 		constraint == LASSO_MESSAGE_FORMAT_XML ||
 		constraint == LASSO_MESSAGE_FORMAT_SOAP) {
 		if (strchr(msg, '<')) {
-			doc = lasso_xml_parse_memory(msg, strlen(msg));
+			doc = lasso_xml_parse_memory(msg, msg_len);
 			if (doc == NULL) {
 				rc = LASSO_MESSAGE_FORMAT_UNKNOWN;
 				goto cleanup;
 			}
 			root = xmlDocGetRootElement(doc);
+			if (! root) {
+				rc = LASSO_MESSAGE_FORMAT_ERROR;
+				goto cleanup;
+			}
 
 			if (any || constraint == LASSO_MESSAGE_FORMAT_SOAP) {
 				gboolean is_soap = FALSE;
@@ -1936,26 +1935,20 @@ lasso_xml_parse_message(const char *message, LassoMessageFormat constraint, xmlD
 				if (is_soap) {
 					root = lasso_xml_get_soap_content(root);
 				}
-				if (! root) {
-					rc = LASSO_MESSAGE_FORMAT_ERROR;
-					goto cleanup;
-				}
 				if (is_soap) {
 					rc = LASSO_MESSAGE_FORMAT_SOAP;
 					goto cleanup;
 				}
-				if (b64) {
-					lasso_release(msg);
-					rc = LASSO_MESSAGE_FORMAT_BASE64;
+				if (rc == LASSO_MESSAGE_FORMAT_BASE64) {
 					goto cleanup;
 				}
 				rc = LASSO_MESSAGE_FORMAT_XML;
-				goto cleanup;
 			}
 		}
 	}
 
 cleanup:
+	lasso_release(base64_decoded_message);
 	if (doc_out) {
 		*doc_out = doc;
 		if (root_out) {
@@ -1963,7 +1956,6 @@ cleanup:
 		}
 	} else {
 		lasso_release_doc(doc);
-		lasso_release_xml_node(root);
 	}
 	return rc;
 }
@@ -2667,36 +2659,30 @@ lasso_xmlsec_load_private_key(const char *filename_or_buffer, const char *passwo
 
 gboolean
 lasso_get_base64_content(xmlNode *node, char **content, size_t *length) {
-	xmlChar *base64, *stripped_base64;
-	xmlChar *result;
-	int base64_length;
-	int rc = 0;
+	xmlChar *base64 = NULL;
+	xmlChar *stripped_base64 = NULL;
+	char *decoded = NULL;
+	int decoded_length = 0;
+	int rc = TRUE;
 
-	if (! node || ! content || ! length)
-		return FALSE;
+	goto_cleanup_if_fail_with_rc(node && content && length, FALSE);
 
 	base64 = xmlNodeGetContent(node);
-	if (! base64)
-		return FALSE;
-	stripped_base64 = base64;
+	goto_cleanup_if_fail_with_rc(base64, FALSE);
+
 	/* skip spaces */
+	stripped_base64 = base64;
 	while (*stripped_base64 && isspace(*stripped_base64))
 		stripped_base64++;
 
-	base64_length = strlen((char*)stripped_base64);
-	result = g_new(xmlChar, base64_length);
-	xmlSecErrorsDefaultCallbackEnableOutput(FALSE);
-	rc = xmlSecBase64Decode(stripped_base64, result, base64_length);
-	xmlSecErrorsDefaultCallbackEnableOutput(TRUE);
-	xmlFree(base64);
-	if (rc < 0) {
-		return FALSE;
-	} else {
-		*content = (char*)g_memdup(result, rc);
-		xmlFree(result);
-		*length = rc;
-		return TRUE;
-	}
+	goto_cleanup_if_fail_with_rc(lasso_base64_decode((char*)stripped_base64, &decoded, &decoded_length), FALSE);
+	lasso_transfer_string(*content, decoded);
+	*length = decoded_length;
+cleanup:
+	lasso_release_xml_string(base64);
+	lasso_release_string(decoded);
+	return rc;
+
 }
 
 xmlSecKeyPtr
@@ -3193,14 +3179,13 @@ static char*
 lasso_get_saml_message(xmlChar **query_fields) {
 	int i = 0;
 	char *enc = NULL;
-	char *message = NULL;
+	char *raw_message = NULL;
+	char *gziped_message = NULL;
+	int gziped_message_len = 0;
 	char *saml_message = NULL;
-	char *decoded_message = NULL;
+	size_t saml_message_len = 0;
 	xmlChar *field = NULL;
 	char *t = NULL;
-	int rc = 0;
-	int len = 0;
-	size_t outlen = 0;
 
 	for (i=0; (field=query_fields[i]); i++) {
 		t = strchr((char*)field, '=');
@@ -3212,11 +3197,11 @@ lasso_get_saml_message(xmlChar **query_fields) {
 			continue;
 		}
 		if (strcmp((char*)field, LASSO_SAML2_FIELD_REQUEST) == 0 || strcmp((char*)field, LASSO_SAML2_FIELD_RESPONSE) == 0) {
-			message = t+1;
+			raw_message = t+1;
 			continue;
 		}
 	}
-	if (message == NULL) {
+	if (raw_message == NULL) {
 		return NULL;
 	}
 	if (enc && strcmp(enc, LASSO_SAML2_DEFLATE_ENCODING) != 0) {
@@ -3224,23 +3209,12 @@ lasso_get_saml_message(xmlChar **query_fields) {
 		debug("Unknown URL encoding: %64s", enc);
 		return NULL;
 	}
-	len = strlen(message);
-	decoded_message = g_malloc(len);
-	if (! is_base64(message)) {
-		debug("message is not base64");
-		goto cleanup;
-	}
-	rc = xmlSecBase64Decode((xmlChar*)message, (xmlChar*)decoded_message, len);
-	if (rc < 0) {
-		debug("could not decode redirect SAML message");
-		goto cleanup;
-	}
-	/* rc contains the length of the result */
-	saml_message = (char*)lasso_inflate((unsigned char*) decoded_message, rc, &outlen);
+
+	goto_cleanup_if_fail(lasso_base64_decode(raw_message, &gziped_message, &gziped_message_len))
+	saml_message = (char*)lasso_inflate((unsigned char*)gziped_message, gziped_message_len, &saml_message_len);
 cleanup:
-	if (decoded_message) {
-		lasso_release(decoded_message);
-	}
+	lasso_release_string(gziped_message);
+
 	return saml_message;
 }
 
@@ -3256,6 +3230,7 @@ lasso_xmltextreader_from_message(const char *message, char **to_free) {
 	char *needle;
 	xmlChar **query_fields = NULL;
 	char *decoded_message = NULL;
+	int decoded_message_len = 0;
 	xmlTextReader *reader = NULL;
 
 	g_assert(to_free);
@@ -3271,22 +3246,17 @@ lasso_xmltextreader_from_message(const char *message, char **to_free) {
 			}
 			len = strlen(message);
 		} else { /* POST */
-			int rc = 0;
-
 			if (! is_base64(message)) {
 				debug("POST message is not base64");
 				goto cleanup;
 			}
-			decoded_message = g_malloc(len);
-			rc = xmlSecBase64Decode((xmlChar*)message, (xmlChar*)decoded_message, len);
-			if (rc < 0) {
+			if (! lasso_base64_decode(message, &decoded_message, &decoded_message_len)) {
 				debug("could not decode POST SAML message");
 				goto cleanup;
 			}
-			len = rc;
-			decoded_message[len] = '\0';
-			message = *to_free = decoded_message;
-			decoded_message = NULL;
+			message = decoded_message;
+			len = decoded_message_len;
+			lasso_transfer_string(*to_free, decoded_message);
 		}
 	}
 
@@ -3294,9 +3264,7 @@ lasso_xmltextreader_from_message(const char *message, char **to_free) {
 		reader = xmlReaderForMemory(message, len, "", NULL, XML_PARSE_NONET);
 
 cleanup:
-	if (query_fields)
-		lasso_release_array_of_xml_strings(query_fields);
-	if (decoded_message)
-		lasso_release_string(decoded_message);
+	lasso_release_array_of_xml_strings(query_fields);
+	lasso_release_string(decoded_message);
 	return reader;
 }
diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c
index a921b2c4..0d5c6e31 100644
--- a/lasso/xml/xml.c
+++ b/lasso/xml/xml.c
@@ -2534,7 +2534,9 @@ is_base64(const char *message)
 LassoMessageFormat
 lasso_node_init_from_message_with_format(LassoNode *node, const char *message, LassoMessageFormat constraint, xmlDoc **doc_out, xmlNode **root_out)
 {
-	char *msg = NULL;
+	char *decoded_msg = NULL;
+	int decoded_msg_len = 0;
+	const char *msg = NULL;
 	gboolean b64 = FALSE;
 	LassoMessageFormat rc = LASSO_MESSAGE_FORMAT_ERROR;
 	xmlDoc *doc = NULL;
@@ -2546,15 +2548,11 @@ lasso_node_init_from_message_with_format(LassoNode *node, const char *message, L
 	/* BASE64 case */
 	if (any || constraint == LASSO_MESSAGE_FORMAT_BASE64) {
 		if (message[0] != 0 && is_base64(message)) {
-			int rc = 0;
-
-			msg = g_malloc(strlen(message));
-			rc = xmlSecBase64Decode((xmlChar*)message, (xmlChar*)msg, strlen(message));
-			if (rc >= 0) {
+			if (lasso_base64_decode(message, &decoded_msg, &decoded_msg_len)) {
 				b64 = TRUE;
+				msg = decoded_msg;
 			} else {
-				lasso_release(msg);
-				msg = (char*)message;
+				msg = message;
 			}
 		}
 	}
@@ -2589,7 +2587,6 @@ lasso_node_init_from_message_with_format(LassoNode *node, const char *message, L
 					goto cleanup;
 				}
 				if (b64) {
-					lasso_release(msg);
 					rc = LASSO_MESSAGE_FORMAT_BASE64;
 					goto cleanup;
 				}
@@ -2612,6 +2609,7 @@ lasso_node_init_from_message_with_format(LassoNode *node, const char *message, L
 	}
 
 cleanup:
+	lasso_release_string(decoded_msg);
 	if (doc_out) {
 		*doc_out = doc;
 		if (root_out) {
openSUSE Build Service is sponsored by