javasamlinflate

Java Inflater throws a DataFormatException "invalid code length set"


I am using the inflater to decompress a SAMLRequest. Since this value is compressed with GZIP i managed to pass "true" to the inflater constructor, in order to provide compatibility with such format. However, the inflating line throws a DataFormatException.

    private String decodeMessage(String SAMLContent) {
        try {
            //URLDecode, Base64 and inflate data

            //URLDecode
            SAMLContent = URLDecoder.decode(SAMLContent, "UTF-8");

            //Base64 decoding
            byte[] decode = Base64.getDecoder().decode(SAMLContent);
            SAMLContent = new String(decode, "UTF-8");
            //SAMLContent = new String(Base64.getDecoder().decode(SAMLContent), "UTF-8");

            //Inflating data
            try {
                byte[] inflated = new byte[(10 * SAMLContent.getBytes("UTF-8").length)];
                Inflater i = new Inflater(true);
                i.setInput(SAMLContent.getBytes("UTF-8"), 0, SAMLContent.getBytes("UTF-8").length);

                //The following line throws DFException
                int finalSize = i.inflate(inflated);

                SAMLContent = new String(SAMLContent.getBytes("UTF-8"), 0, finalSize, "UTF-8");
                i.end();

            } catch (DataFormatException ex) {
                JOptionPane.showMessageDialog(null, "DFE: " + ex.getMessage());  //Returns "invalid code length set"
            }

        } catch (UnsupportedEncodingException ex) {
            JOptionPane.showMessageDialog(null, "UEE: " + ex.getMessage());
        }

        return SAMLContent;
    }

The exception is raised at line 20. The workflow I'm trying to replicate is

  1. Copying the value of the request (This one for instance)
  2. Use this URL decoder to decode it (the bottom-left textbox)
  3. Paste the result of the second step in this Base64decoder + inflater in order to get the original XML, as shown in the third textbox of the last page.

Solution

  • It was a problem of the several conversions between byte array and string, which was probably causing an information loss somewhere. This is the working code I am using.

    private String decodeHeader(String SAMLContent) {
        try {
            SAMLContent = URLDecoder.decode(SAMLContent, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            JOptionPane.showMessageDialog(null, "UEException: " + ex.getMessage());
        }
    
        byte[] deflatedBytes = Base64.getDecoder().decode(SAMLContent);
        byte[] inflatedBytes = new byte[100*deflatedBytes.length];
        Inflater compressor = new Inflater(true);
    
        compressor.setInput(deflatedBytes, 0, deflatedBytes.length);
    
        try {
            int size = compressor.inflate(inflatedBytes);
        } catch (DataFormatException ex) {
            JOptionPane.showMessageDialog(null, "DFException: " + ex.getMessage());
        }
    
        try {
            return new String(inflatedBytes, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
            JOptionPane.showMessageDialog(null, "UEException: " + ex.getMessage());
        }
        JOptionPane.showConfirmDialog(null, "This shouln't be printed");
        return null;
    }