Cannot verify signature of encrypted SAML assertion (when the assertion, not the response, is signed)

Hi, I'm using ComponentPro.Saml.dll in a service provider, with Azure as the identity provider, and I cannot verify the signature of an encrypted assertion. Consider 3 scenarios: 1. A response **is** signed, and the assertion within the response **is** also signed. 2. A response **is** signed, and the assertion within the response is **not** signed. 3. A response is **not** signed, but the assertion within the response **is** signed. When the assertion is **not** encrypted, in all 3 of the above scenarios, Response.IsSigned() returns true and Response.Validate(X509Certificate2) also returns true. This is unexpected in scenario 3, because the response is **not** signed - only the assertion is signed. It appears that the ComponentPro.Saml2.Response class exposes the assertion's signature through Response.SignatureElement if no /Response/Signature element exists in the received XML. This is very confusing - when looking at Response.ToString(), I thought that Azure was signing incorrectly; only by pulling the raw SAMLResponse form field from the HttpRequest object did I realize that it's the Response object that is behaving unexpectedly. When the assertion **is** encrypted, Response.IsSigned() and Response.Validate(X509Certificate2) only return true in scenarios 1 and 2. In scenario 3, Response.IsSigned() returns false. This is the behaviour I actually expected, but there's a problem in that while Response.GetEncryptedAssertion().Decrypt(X509Certificate2).IsSigned() returns true in scenario 3, Response.GetEncryptedAssertion().Decrypt(X509Certificate2).Validate(X509Certificate2) seems to always return false. (And I know that there isn't a problem with the signing/encryption certificates, because I can successfully decrypt the assertion and verify the signature at the SAML response level.) So unless I've misunderstood something, it appears that there are a couple of bugs: 1. Response.SignatureElement exposes the assertion's signature (and Response.IsSigned() returns true) even when the response itself is **not** signed. 2. Response.GetEncryptedAssertion().Decrypt(X509Certificate2).Validate(X509Certificate2) always returns false, even when an encrypted *assertion* **is** correctly signed in a *response* that is **not** signed. Issue #2 is most critical, because I cannot find any way to verify the signature of an encrypted assertion when the response itself is not signed. Can you please tell me what I'm doing wrong, or - if it is actually a bug - whether there's a work-around and/or when the issue can be fixed? P.S. I am aware that I could configure Azure to always sign the response and never sign the assertion, and then I would be able to verify the response's signature regardless of whether the assertion was encrypted or not; however, the identity provider's configuration is not always within my control. I am also aware that encrypting the assertion is not necessary in an HTTPS environment, but, again, whether or not the assertion is encrypted is not always within my control. I really need to be able to verify the signature of an encrypted assertion when the response itself is not signed.
asked 6/2/2021 9:49:26 PM
add a comment

0 Answers

Your Answer

Not the answer you're looking for? Browse other questions tagged saml or ask your own question.