0

i am using c++ zlib to deflate a XML string that gives the output:

<samlp:AuthnRequest
  xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
  ID="idnumber"
  Version="2.0" IssueInstant="2026-09-30T15:12:00.1839884Z"
  xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
  <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">tenantID</Issuer>
</samlp:AuthnRequest>

the xml is put into a stringstream as follow with rapidxml:

xml << "<samlp:AuthnRequest \n" <<
     "xmlns=\"urn:oasis:names:tc:SAML:2.0:metadata\" \n " <<
     "ID=\"idnumber\" \n " <<
     "Version=\"2.0\" IssueInstant=\"2022-09-30T16:00:00.1839884Z\"\n " <<
     "xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">\n" <<
     "<Issuer xmlns=\"urn:oasis:names:tc:SAML:2.0:assertion\">" + tenantIDstring + "</Issuer>\n" <<     "</samlp:AuthnRequest>";

When i deflate and then b64 encode then url encode it, it returns thestring that should be sent over the url for the SAMLRequest of azure AD. So its working as it should and is deflating the xml.

But the response from Azure AD return that the request is not deflated propperly. i am using the deflate.h from zlib.

deflate_xml.h:

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <string>
#include <vector>
#include <iostream>
#include "rapidxml.hpp"
#include <zlib.h>

namespace helper
{
    static std::string deflate_file(const std::string &str, // gets filled with xml.str(); from the main.cpp
                        int compressionlevel = Z_BEST_COMPRESSION)
    {
        z_stream zs; // z_stream is zlib's control structure
        memset(&zs, 0, sizeof(zs));

        if (deflateInit(&zs, compressionlevel) != Z_OK)
            throw(std::runtime_error("deflateInit failed while compressing."));

        zs.next_in = (Bytef *)str.data();
        zs.avail_in = str.size(); // set the z_stream's input

        int ret;
        char outbuffer[32768];
        std::string outstring;

        // retrieve the compressed bytes blockwise
        do
        {
            zs.next_out = reinterpret_cast<Bytef *>(outbuffer);
            zs.avail_out = sizeof(outbuffer);

            ret = deflate(&zs, Z_FINISH);

            if (outstring.size() < zs.total_out)
            {
                // append the block to the output string
                outstring.append(outbuffer,
                                 zs.total_out - outstring.size());
            }
        } while (ret == Z_OK);

        deflateEnd(&zs);

        if (ret != Z_STREAM_END)
        { // an error occurred that was not EOF
            std::ostringstream oss;
            oss << "Exception during zlib compression: (" << ret << ") " << zs.msg;
            throw(std::runtime_error(oss.str()));
        }

        return outstring;
    }

Whats seems to be going amis here. Am i using the wrong deflation algorithm ? When i upload te xml string to a online deflate b64 enc. it gives me a string that is viable as a SAMLRequest. What diffrence is there in the zlib deflate and the online deflation ? (ref. https://developers.onelogin.com/saml/online-tools/code-decode/deflate-base64-encode)

Update:

Seems the online encoder in the ref, does something diffrent. I took the deflated example and put that in a diffrent base 64 encoder online. And now azure AD says its not base 64 encoded properly.. does anyone know what the difference is between the "normal deflation and standalone base64"and the one that certain website does ?

  • "But the response from Azure AD return that the request is not deflated propperly". What is the _exact_ response from Azure AD? What does the Azure AD documentation say that it is expecting? – Mark Adler Oct 03 '22 at 19:46
  • Well. i cant find that much on deflation on azure documentation.. the response is: AADSTS750055: SAML message was not properly DEFLATE-encoded. When i look up what it means i only get refs to posts that have the BASE64 encoding issue. When i post it in Azure AD debug it says: Root cause: Azure AD doesn’t support the SAML request sent by the application for Single sign-on. Some common issues are:​​ Missing required fields in the SAML request SAML request encoded method. But that same xml.str() output when deflated and base64 encoded by the ref website, allows me to login. – kees prince Oct 03 '22 at 20:31

1 Answers1

0

From the reference online encoding linked in the question, Azure AD is expecting raw deflate data. To get that, replace the deflateInit() call with:

deflateInit2(&zs, compressionlevel, 8, -15, 8, 0)
Mark Adler
  • 101,978
  • 13
  • 118
  • 158