Description
When handling an IdP-initiated LogoutRequest, with sign=True and redirect binding, the LogoutResponse gets a signature in an XML element (client.create_logout_response). The XML is then deflated and Base64-encoded, and inserted in a URL as a SAMLResponse parameter. This parameter is then signed again (client.apply_binding), with the signature put in another parameter, and the whole url returned.
This double-signing causes the IdP I'm interfacing with to reject the resulting response, and there's no option to just sign once. When only doing the outermost signing, the response goes through and logout is successful.
Excerpt from client.py:
response = self.create_logout_response(
_req.message,
bindings=response_bindings,
status=status,
sign=False, # <-- Only sign once
# sign=sign,
# sign_alg=sign_alg,
digest_alg=digest_alg,
)
rinfo = self.response_args(_req.message, response_bindings)
return self.apply_binding(
rinfo["binding"],
response,
rinfo["destination"],
relay_state,
response=True,
sign=sign,
sigalg=sign_alg,
)
The innermost signature also contains newline escapes (base64'd string contains '\n'), failing validation with XSD: https://docs.oasis-open.org/security/saml/v2.0/saml-schema-protocol-2.0.xsd, but forgoing the innermost signature makes this a non-issue.
Code Version
7.2.1
Expected Behavior
An option is present to sign in xml, sign in urlparam, or both
Current Behavior
Only signature in both places can be done.
Possible Solution
Add option in method signature, or an explanation why both signatures are necessary.
Steps to Reproduce
- Initiate a logoutrequest from an IdP
- Analyze the response from SP; observe that the request contains a Signature parameter, and base64-decoding and inflating the SAMLResponse parameter reveals a second signature.
It's likely that this behavior is intended, but some IdPs reject the response, necessitating an option to sign just once.