From ebee5d4d2c2543df78577b654bd2cea827be1861 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Tue, 15 Nov 2022 17:11:40 +0100 Subject: [PATCH] wip --- lasso/xml/private.h | 4 +- lasso/xml/tools.c | 414 +++++++++++++++++++++----------------------- 2 files changed, 202 insertions(+), 216 deletions(-) diff --git a/lasso/xml/private.h b/lasso/xml/private.h index a60d064c..4aa590a4 100644 --- a/lasso/xml/private.h +++ b/lasso/xml/private.h @@ -218,9 +218,9 @@ xmlSecKeysMngr* lasso_load_certs_from_pem_certs_chain_file (const char *file); char* lasso_query_sign(char *query, LassoSignatureContext signature_context); -int lasso_query_verify_signature(const char *query, const xmlSecKey *public_key); +int lasso_query_verify_signature(const char *query, xmlSecKey *public_key); -int lasso_saml2_query_verify_signature(const char *query, const xmlSecKey *sender_public_key); +int lasso_saml2_query_verify_signature(const char *query, xmlSecKey *sender_public_key); char* lasso_sha1(const char *str); diff --git a/lasso/xml/tools.c b/lasso/xml/tools.c index 820c273b..8cd178c3 100644 --- a/lasso/xml/tools.c +++ b/lasso/xml/tools.c @@ -46,10 +46,6 @@ #include #include -#include -#include -#include -#include #include #include @@ -60,6 +56,7 @@ #include #include #include +#include #include @@ -481,22 +478,23 @@ char* lasso_query_sign(char *query, LassoSignatureContext context) { char *digest = NULL; /* 160 bit buffer */ - RSA *rsa = NULL; - DSA *dsa = NULL; unsigned char *sigret = NULL; - unsigned int siglen = 0; + size_t siglen = 0; xmlChar *b64_sigret = NULL, *e_b64_sigret = NULL; char *new_query = NULL, *s_new_query = NULL; int status = 0; const xmlChar *algo_href = NULL; - char *hmac_key; + unsigned char *hmac_key; size_t hmac_key_length; - const EVP_MD *md = NULL; xmlSecKey *key; xmlSecKeyData *key_data; - unsigned int sigret_size = 0; LassoSignatureMethod sign_method; - lasso_error_t rc = 0; + lasso_error_t rc = 0; + + const EVP_MD *md = NULL; + EVP_MD_CTX *evp_md_ctx = NULL; + EVP_PKEY *pkey = NULL; + EVP_PKEY *hmac_pkey = NULL; g_return_val_if_fail(query != NULL, NULL); g_return_val_if_fail(lasso_ok_signature_method(context.signature_method), NULL); @@ -546,118 +544,89 @@ lasso_query_sign(char *query, LassoSignatureContext context) xmlFree(BAD_CAST t); } - /* build buffer digest */ + /* define the digest algorithm */ switch (sign_method) { case LASSO_SIGNATURE_METHOD_RSA_SHA1: case LASSO_SIGNATURE_METHOD_DSA_SHA1: - digest = lasso_sha1(new_query); + case LASSO_SIGNATURE_METHOD_HMAC_SHA1: + md = EVP_sha1(); break; case LASSO_SIGNATURE_METHOD_RSA_SHA256: - digest = lasso_sha256(new_query); + case LASSO_SIGNATURE_METHOD_HMAC_SHA256: + md = EVP_sha256(); break; case LASSO_SIGNATURE_METHOD_RSA_SHA384: - digest = lasso_sha384(new_query); + case LASSO_SIGNATURE_METHOD_HMAC_SHA384: + md = EVP_sha384(); break; case LASSO_SIGNATURE_METHOD_RSA_SHA512: - digest = lasso_sha512(new_query); - default: + case LASSO_SIGNATURE_METHOD_HMAC_SHA512: + md = EVP_sha512(); break; + case LASSO_SIGNATURE_METHOD_NONE: + case LASSO_SIGNATURE_METHOD_LAST: + g_assert_not_reached(); } + + /* Get the signture key */ switch (sign_method) { case LASSO_SIGNATURE_METHOD_RSA_SHA1: - case LASSO_SIGNATURE_METHOD_DSA_SHA1: case LASSO_SIGNATURE_METHOD_RSA_SHA256: case LASSO_SIGNATURE_METHOD_RSA_SHA384: case LASSO_SIGNATURE_METHOD_RSA_SHA512: - if (digest == NULL) { - message(G_LOG_LEVEL_CRITICAL, "Failed to build the buffer digest"); + case LASSO_SIGNATURE_METHOD_DSA_SHA1: + pkey = xmlSecOpenSSLEvpKeyDataGetEvp(key_data); + if (! pkey) { + message(G_LOG_LEVEL_CRITICAL, "Failed to get assymetric key"); goto done; } - default: - break; - } - /* extract the OpenSSL key */ - switch (sign_method) { - case LASSO_SIGNATURE_METHOD_RSA_SHA1: - case LASSO_SIGNATURE_METHOD_RSA_SHA256: - case LASSO_SIGNATURE_METHOD_RSA_SHA384: - case LASSO_SIGNATURE_METHOD_RSA_SHA512: - rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key_data); - g_assert(rsa); - /* alloc memory for sigret */ - sigret_size = RSA_size(rsa); - break; - case LASSO_SIGNATURE_METHOD_DSA_SHA1: - dsa = xmlSecOpenSSLKeyDataDsaGetDsa(key_data); - g_assert(dsa); - /* alloc memory for sigret */ - sigret_size = DSA_size(dsa); break; case LASSO_SIGNATURE_METHOD_HMAC_SHA1: - md = EVP_sha1(); - sigret_size = EVP_MD_size(md); - break; case LASSO_SIGNATURE_METHOD_HMAC_SHA256: - md = EVP_sha256(); - sigret_size = EVP_MD_size(md); - break; case LASSO_SIGNATURE_METHOD_HMAC_SHA384: - md = EVP_sha384(); - sigret_size = EVP_MD_size(md); - break; case LASSO_SIGNATURE_METHOD_HMAC_SHA512: - md = EVP_sha512(); - sigret_size = EVP_MD_size(md); + if ((rc = lasso_get_hmac_key(key, (void**)&hmac_key, + &hmac_key_length))) { + message(G_LOG_LEVEL_CRITICAL, "Failed to get hmac key (%s)", lasso_strerror(rc)); + goto done; + } + g_assert(hmac_key); + hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, hmac_key, (int)hmac_key_length); + if (! hmac_key) { + message(G_LOG_LEVEL_CRITICAL, "EVP_PKEY_new_mac_key failed"); + goto done; + } + pkey = hmac_pkey; break; - default: + case LASSO_SIGNATURE_METHOD_LAST: + case LASSO_SIGNATURE_METHOD_NONE: g_assert_not_reached(); } - sigret = (unsigned char *)g_malloc (sigret_size); switch (sign_method) { case LASSO_SIGNATURE_METHOD_RSA_SHA1: - /* sign digest message */ - status = RSA_sign(NID_sha1, (unsigned char*)digest, SHA_DIGEST_LENGTH, sigret, - &siglen, rsa); - break; case LASSO_SIGNATURE_METHOD_RSA_SHA256: - /* sign digest message */ - status = RSA_sign(NID_sha256, (unsigned char*)digest, SHA256_DIGEST_LENGTH, sigret, - &siglen, rsa); - break; case LASSO_SIGNATURE_METHOD_RSA_SHA384: - /* sign digest message */ - status = RSA_sign(NID_sha384, (unsigned char*)digest, SHA384_DIGEST_LENGTH, sigret, - &siglen, rsa); - break; case LASSO_SIGNATURE_METHOD_RSA_SHA512: - /* sign digest message */ - status = RSA_sign(NID_sha512, (unsigned char*)digest, SHA512_DIGEST_LENGTH, sigret, - &siglen, rsa); - break; case LASSO_SIGNATURE_METHOD_DSA_SHA1: - status = DSA_sign(NID_sha1, (unsigned char*)digest, SHA_DIGEST_LENGTH, sigret, - &siglen, dsa); - break; case LASSO_SIGNATURE_METHOD_HMAC_SHA1: case LASSO_SIGNATURE_METHOD_HMAC_SHA256: case LASSO_SIGNATURE_METHOD_HMAC_SHA384: case LASSO_SIGNATURE_METHOD_HMAC_SHA512: - if ((rc = lasso_get_hmac_key(key, (void**)&hmac_key, - &hmac_key_length))) { - message(G_LOG_LEVEL_CRITICAL, "Failed to get hmac key (%s)", lasso_strerror(rc)); + evp_md_ctx = EVP_MD_CTX_create(); + if (EVP_DigestSignInit(evp_md_ctx, NULL, md, NULL, pkey) <= 0) { + message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSignInit failed"); goto done; } - g_assert(hmac_key); - - /* key should be at least 128 bits long */ - if (hmac_key_length < 16) { - critical("HMAC key should be at least 128 bits long"); + if (EVP_DigestSign(evp_md_ctx, NULL, &siglen, (unsigned char*)new_query, strlen(new_query)) <= 0) { + message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSign failed"); + goto done; + } + sigret = g_malloc(siglen); + if (EVP_DigestSign(evp_md_ctx, sigret, &siglen, (unsigned char*)new_query, strlen(new_query)) <= 0) { + message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSign failed"); goto done; } - - HMAC(md, hmac_key, hmac_key_length, (unsigned char *)new_query, - strlen(new_query), sigret, &siglen); status = 1; break; case LASSO_SIGNATURE_METHOD_LAST: @@ -665,14 +634,13 @@ lasso_query_sign(char *query, LassoSignatureContext context) g_assert_not_reached(); } - g_assert(siglen == sigret_size); if (status == 0) { goto done; } /* Base64 encode the signature value */ - b64_sigret = xmlSecBase64Encode(sigret, sigret_size, 0); + b64_sigret = xmlSecBase64Encode(sigret, siglen, 0); /* escape b64_sigret */ e_b64_sigret = lasso_xmlURIEscapeStr((xmlChar*)b64_sigret, NULL); @@ -701,7 +669,15 @@ done: lasso_release(sigret); lasso_release_xml_string(b64_sigret); lasso_release_xml_string(e_b64_sigret); - + if (evp_md_ctx) { + EVP_MD_CTX_free(evp_md_ctx); + evp_md_ctx = NULL; + } + if (hmac_pkey) { + EVP_PKEY_free(hmac_pkey); + hmac_pkey = NULL; + pkey = NULL; + } return s_new_query; } @@ -728,153 +704,162 @@ lasso_assertion_encrypt(LassoSaml2Assertion *assertion, char *recipient) static lasso_error_t lasso_query_verify_helper(const char *signed_content, const char *b64_signature, const char *algorithm, - const xmlSecKey *key) + xmlSecKey *key) { - RSA *rsa = NULL; - DSA *dsa = NULL; char *digest = NULL; - xmlSecByte *signature = NULL; - int key_size = 0; + xmlSecByte signature[1024] = {0}; + xmlSecSize signature_len = 0; unsigned char *hmac_key = NULL; size_t hmac_key_length = 0; const EVP_MD *md = NULL; lasso_error_t rc = 0; LassoSignatureMethod method = LASSO_SIGNATURE_METHOD_NONE; - size_t digest_size = 1; - int type = -1; + EVP_PKEY *hmac_pkey = NULL; + unsigned char *new_signature = NULL; + EVP_MD_CTX *evp_md_ctx = NULL; if (lasso_strisequal(algorithm, (char*)xmlSecHrefRsaSha1)) { goto_cleanup_if_fail_with_rc(key->value->id == xmlSecOpenSSLKeyDataRsaId, LASSO_DS_ERROR_INVALID_SIGALG) - rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key->value); - key_size = RSA_size(rsa); method = LASSO_SIGNATURE_METHOD_RSA_SHA1; - digest_size = SHA_DIGEST_LENGTH; - type = NID_sha1; } else if (lasso_strisequal(algorithm, (char*)xmlSecHrefDsaSha1)) { goto_cleanup_if_fail_with_rc(key->value->id == xmlSecOpenSSLKeyDataDsaId, LASSO_DS_ERROR_INVALID_SIGALG); - dsa = xmlSecOpenSSLKeyDataDsaGetDsa(key->value); - key_size = DSA_size(dsa); method = LASSO_SIGNATURE_METHOD_DSA_SHA1; - digest_size = SHA_DIGEST_LENGTH; - type = NID_sha1; } else if (lasso_strisequal(algorithm, (char*)xmlSecHrefRsaSha256)) { goto_cleanup_if_fail_with_rc(key->value->id == xmlSecOpenSSLKeyDataRsaId, LASSO_DS_ERROR_INVALID_SIGALG) - rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key->value); - key_size = RSA_size(rsa); method = LASSO_SIGNATURE_METHOD_RSA_SHA256; - digest_size = SHA256_DIGEST_LENGTH; - type = NID_sha256; } else if (lasso_strisequal(algorithm, (char*)xmlSecHrefRsaSha384)) { goto_cleanup_if_fail_with_rc(key->value->id == xmlSecOpenSSLKeyDataRsaId, LASSO_DS_ERROR_INVALID_SIGALG) - rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key->value); - key_size = RSA_size(rsa); method = LASSO_SIGNATURE_METHOD_RSA_SHA384; - digest_size = SHA384_DIGEST_LENGTH; - type = NID_sha384; } else if (lasso_strisequal(algorithm, (char*)xmlSecHrefRsaSha512)) { goto_cleanup_if_fail_with_rc(key->value->id == xmlSecOpenSSLKeyDataRsaId, LASSO_DS_ERROR_INVALID_SIGALG) - rsa = xmlSecOpenSSLKeyDataRsaGetRsa(key->value); - key_size = RSA_size(rsa); method = LASSO_SIGNATURE_METHOD_RSA_SHA512; - digest_size = SHA512_DIGEST_LENGTH; - type = NID_sha512; } else if (lasso_strisequal(algorithm, (char*)xmlSecHrefHmacSha1)) { lasso_check_good_rc(lasso_get_hmac_key(key, (void**)&hmac_key, &hmac_key_length)); - md = EVP_sha1(); - key_size = EVP_MD_size(md); method = LASSO_SIGNATURE_METHOD_HMAC_SHA1; } else if (lasso_strisequal(algorithm, (char*)xmlSecHrefHmacSha256)) { lasso_check_good_rc(lasso_get_hmac_key(key, (void**)&hmac_key, &hmac_key_length)); - md = EVP_sha256(); - key_size = EVP_MD_size(md); method = LASSO_SIGNATURE_METHOD_HMAC_SHA256; } else if (lasso_strisequal(algorithm, (char*)xmlSecHrefHmacSha384)) { lasso_check_good_rc(lasso_get_hmac_key(key, (void**)&hmac_key, &hmac_key_length)); - md = EVP_sha384(); - key_size = EVP_MD_size(md); method = LASSO_SIGNATURE_METHOD_HMAC_SHA384; } else if (lasso_strisequal(algorithm, (char*)xmlSecHrefHmacSha512)) { lasso_check_good_rc(lasso_get_hmac_key(key, (void**)&hmac_key, &hmac_key_length)); - md = EVP_sha512(); - key_size = EVP_MD_size(md); method = LASSO_SIGNATURE_METHOD_HMAC_SHA512; } else { goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGALG); } - /* is the signature algo allowed */ - goto_cleanup_if_fail_with_rc( - lasso_allowed_signature_method(method), - LASSO_DS_ERROR_INVALID_SIGALG); - - /* decode signature */ - signature = g_malloc(key_size+1); - goto_cleanup_if_fail_with_rc( - xmlSecBase64Decode((xmlChar*)b64_signature, signature, key_size+1) != 0, - LASSO_DS_ERROR_INVALID_SIGNATURE); - /* digest */ + /* define the digest algorithm */ switch (method) { case LASSO_SIGNATURE_METHOD_RSA_SHA1: case LASSO_SIGNATURE_METHOD_DSA_SHA1: - digest = lasso_sha1(signed_content); + case LASSO_SIGNATURE_METHOD_HMAC_SHA1: + md = EVP_sha1(); break; case LASSO_SIGNATURE_METHOD_RSA_SHA256: - digest = lasso_sha256(signed_content); + case LASSO_SIGNATURE_METHOD_HMAC_SHA256: + md = EVP_sha256(); break; case LASSO_SIGNATURE_METHOD_RSA_SHA384: - digest = lasso_sha384(signed_content); + case LASSO_SIGNATURE_METHOD_HMAC_SHA384: + md = EVP_sha384(); break; case LASSO_SIGNATURE_METHOD_RSA_SHA512: - digest = lasso_sha512(signed_content); - break; - case LASSO_SIGNATURE_METHOD_HMAC_SHA1: - case LASSO_SIGNATURE_METHOD_HMAC_SHA256: - case LASSO_SIGNATURE_METHOD_HMAC_SHA384: case LASSO_SIGNATURE_METHOD_HMAC_SHA512: + md = EVP_sha512(); break; - default: + case LASSO_SIGNATURE_METHOD_NONE: + case LASSO_SIGNATURE_METHOD_LAST: g_assert_not_reached(); } + + /* is the signature algo allowed */ + goto_cleanup_if_fail_with_rc( + lasso_allowed_signature_method(method), + LASSO_DS_ERROR_INVALID_SIGALG); + + /* decode signature */ + goto_cleanup_if_fail_with_rc( + xmlSecBase64Decode_ex((xmlChar*)b64_signature, signature, 1024, &signature_len) == 0, + LASSO_DS_ERROR_INVALID_SIGNATURE); /* verify signature */ + evp_md_ctx = EVP_MD_CTX_create(); + switch (method) { case LASSO_SIGNATURE_METHOD_RSA_SHA1: case LASSO_SIGNATURE_METHOD_RSA_SHA256: case LASSO_SIGNATURE_METHOD_RSA_SHA384: case LASSO_SIGNATURE_METHOD_RSA_SHA512: - goto_cleanup_if_fail_with_rc( - RSA_verify( - type, - (unsigned char*)digest, - digest_size, - signature, - key_size, rsa) == 1, - LASSO_DS_ERROR_INVALID_SIGNATURE); - break; case LASSO_SIGNATURE_METHOD_DSA_SHA1: - goto_cleanup_if_fail_with_rc( - DSA_verify( - type, - (unsigned char*)digest, - digest_size, - signature, - key_size, dsa) == 1, - LASSO_DS_ERROR_INVALID_SIGNATURE); + { + xmlSecKeyData *key_data = xmlSecKeyGetValue(key); + if (! key_data) { + message(G_LOG_LEVEL_CRITICAL, "Failed to get KeyData"); + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + EVP_PKEY *pkey = xmlSecOpenSSLEvpKeyDataGetEvp(key_data); + if (! pkey) { + message(G_LOG_LEVEL_CRITICAL, "Failed to get assymetric key"); + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + if (1 != EVP_DigestVerifyInit(evp_md_ctx, NULL, md, NULL, pkey)) { + message(G_LOG_LEVEL_CRITICAL, "EVP_DigestVerifyInit failed"); + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + if (1 != EVP_DigestVerifyUpdate(evp_md_ctx, signed_content, strlen(signed_content))) { + message(G_LOG_LEVEL_CRITICAL, "EVP_DigestVerifyUpdate failed"); + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + if(1 != EVP_DigestVerifyFinal(evp_md_ctx, signature, signature_len)) { + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + } break; case LASSO_SIGNATURE_METHOD_HMAC_SHA1: case LASSO_SIGNATURE_METHOD_HMAC_SHA256: case LASSO_SIGNATURE_METHOD_HMAC_SHA384: case LASSO_SIGNATURE_METHOD_HMAC_SHA512: - digest = g_malloc(key_size); - HMAC(md, hmac_key, hmac_key_length, (unsigned char*)signed_content, - strlen(signed_content), (unsigned char*)digest, NULL); + { + unsigned char *hmac_key; + size_t hmac_key_length; + size_t new_signature_len; + + if ((rc = lasso_get_hmac_key(key, (void**)&hmac_key, + &hmac_key_length))) { + message(G_LOG_LEVEL_CRITICAL, "Failed to get hmac key (%s)", lasso_strerror(rc)); + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + g_assert(hmac_key); + hmac_pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, hmac_key, (int)hmac_key_length); + if (! hmac_key) { + message(G_LOG_LEVEL_CRITICAL, "EVP_PKEY_new_mac_key failed"); + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } - goto_cleanup_if_fail_with_rc(lasso_crypto_memequal(digest, signature, - key_size), - LASSO_DS_ERROR_INVALID_SIGNATURE); + if (EVP_DigestSignInit(evp_md_ctx, NULL, md, NULL, hmac_pkey) != 1) { + message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSignInit failed"); + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + if (EVP_DigestSign(evp_md_ctx, NULL, &new_signature_len, (unsigned char*)signed_content, strlen(signed_content)) != 1) { + message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSign failed"); + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + if (new_signature_len != signature_len) { + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + new_signature = g_malloc(new_signature_len); + if (EVP_DigestSign(evp_md_ctx, new_signature, &new_signature_len, (unsigned char*)signed_content, strlen(signed_content)) != 1) { + message(G_LOG_LEVEL_CRITICAL, "EVP_DigestSign failed"); + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + if (CRYPTO_memcmp(signature, new_signature, signature_len) != 0) { + goto_cleanup_with_rc(LASSO_DS_ERROR_INVALID_SIGNATURE); + } + } break; case LASSO_SIGNATURE_METHOD_NONE: case LASSO_SIGNATURE_METHOD_LAST: @@ -882,7 +867,15 @@ lasso_query_verify_helper(const char *signed_content, const char *b64_signature, } cleanup: lasso_release_string(digest); - lasso_release_string(signature); + lasso_release_string(new_signature); + if (evp_md_ctx) { + EVP_MD_CTX_free(evp_md_ctx); + evp_md_ctx = NULL; + } + if (hmac_pkey) { + EVP_PKEY_free(hmac_pkey); + hmac_pkey = NULL; + } return rc; } @@ -899,7 +892,7 @@ cleanup: * a negative value if an error occurs during verification **/ lasso_error_t -lasso_query_verify_signature(const char *query, const xmlSecKey *sender_public_key) +lasso_query_verify_signature(const char *query, xmlSecKey *sender_public_key) { gchar **str_split = NULL; char *b64_signature = NULL; @@ -958,7 +951,7 @@ cleanup: * Return value: 0 if signature is validated, an error code otherwise. */ int -lasso_saml2_query_verify_signature(const char *query, const xmlSecKey *sender_public_key) +lasso_saml2_query_verify_signature(const char *query, xmlSecKey *sender_public_key) { char *b64_signature = NULL; char *query_copy = NULL; @@ -1364,12 +1357,13 @@ 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; @@ -1398,6 +1392,7 @@ lasso_inflate(unsigned char *input, size_t len) } output[zstr.total_out] = 0; inflateEnd(&zstr); + *outlen = zstr.total_out; return output; } @@ -1406,36 +1401,31 @@ lasso_inflate(unsigned char *input, size_t len) gboolean lasso_node_init_from_deflated_query_part(LassoNode *node, char *deflate_string) { - int len; - xmlChar *b64_zre, *zre, *re; - xmlDoc *doc; - xmlNode *root; - - 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; - } + xmlChar *buffer= NULL; + xmlSecSize buffer_len = 0; + xmlChar *re = NULL; + size_t re_len = 0; + xmlDoc *doc = NULL; + xmlNode *root = NULL; + gboolean rc = TRUE; - re = lasso_inflate(zre, len); - xmlFree(zre); + buffer = (xmlChar*)xmlURIUnescapeString(deflate_string, 0, NULL); + goto_cleanup_if_fail_with_rc(xmlSecBase64DecodeInPlace(buffer, &buffer_len) == 0, FALSE); - if (! re) - return FALSE; + re = lasso_inflate(buffer, buffer_len, &re_len); + goto_cleanup_if_fail_with_rc_with_warning(re != NULL, FALSE); doc = lasso_xml_parse_memory((char*)re, strlen((char*)re)); - lasso_release_string(re); + goto_cleanup_if_fail_with_rc_with_warning(doc != NULL, FALSE); root = xmlDocGetRootElement(doc); lasso_node_init_from_xml(node, root); - lasso_release_doc(doc); - return TRUE; +cleanup: + lasso_release_xml_string(buffer); + lasso_release_doc(doc); + lasso_release_string(re); + return rc; } char* @@ -1897,24 +1887,24 @@ LassoMessageFormat lasso_xml_parse_message(const char *message, LassoMessageFormat constraint, xmlDoc **doc_out, xmlNode **root_out) { char *msg = NULL; - gboolean b64 = FALSE; + xmlSecSize msg_len = 0; LassoMessageFormat rc = LASSO_MESSAGE_FORMAT_UNKNOWN; xmlDoc *doc = NULL; xmlNode *root = NULL; gboolean any = constraint == LASSO_MESSAGE_FORMAT_UNKNOWN; - msg = (char*)message; + msg = g_strdup(message); + msg_len = strlen(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; + if (xmlSecBase64DecodeInPlace((xmlChar*)msg, &msg_len) == 0) { + rc = LASSO_MESSAGE_FORMAT_BASE64; } else { lasso_release(msg); - msg = (char*)message; + msg = g_strdup(message); + msg_len = strlen(message); } } } @@ -1924,12 +1914,16 @@ lasso_xml_parse_message(const char *message, LassoMessageFormat constraint, xmlD 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; @@ -1938,26 +1932,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(msg); if (doc_out) { *doc_out = doc; if (root_out) { @@ -1965,7 +1953,6 @@ cleanup: } } else { lasso_release_doc(doc); - lasso_release_xml_node(root); } return rc; } @@ -2529,13 +2516,11 @@ lasso_base64_decode(const char *from, char **buffer, int *buffer_len) *buffer = g_malloc0(len); xmlSecErrorsDefaultCallbackEnableOutput(FALSE); - ret = xmlSecBase64Decode(BAD_CAST from, BAD_CAST *buffer, len); - xmlSecErrorsDefaultCallbackEnableOutput(TRUE); - if (ret <= 0) { + ret = xmlSecBase64Decode_ex(BAD_CAST from, BAD_CAST *buffer, len, (xmlSecSize*)buffer_len); + if (ret != 0) { lasso_release_string(*buffer); return FALSE; } - *buffer_len = ret; return TRUE; } @@ -2559,10 +2544,10 @@ lasso_xmlURIEscapeStr(const xmlChar *from, const xmlChar *list) int ri; if (list == NULL) - list = ""; + list = (xmlChar*)""; for (fp = from; *fp; fp++) { - if (isalnum(*fp) || strchr("._~-", *fp) || strchr(list, *fp)) + if (isalnum(*fp) || strchr("._~-", *fp) || strchr((char*)list, *fp)) len++; else len += 3; @@ -2572,7 +2557,7 @@ lasso_xmlURIEscapeStr(const xmlChar *from, const xmlChar *list) ri = 0; for (fp = from; *fp; fp++) { - if (isalnum(*fp) || strchr("._~-", *fp) || strchr(list, *fp)) { + if (isalnum(*fp) || strchr("._~-", *fp) || strchr((char*)list, *fp)) { result[ri++] = *fp; } else { int msb = (*fp & 0xf0) >> 4; @@ -3168,6 +3153,7 @@ lasso_get_saml_message(xmlChar **query_fields) { char *enc = NULL; char *message = NULL; char *saml_message = NULL; + size_t saml_message_len = 0; char *decoded_message = NULL; xmlChar *field = NULL; char *t = NULL; @@ -3208,7 +3194,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, &saml_message_len); cleanup: if (decoded_message) { lasso_release(decoded_message); -- 2.37.2