Hi,
I'm using ComponentPro.Saml.dll 7.2.40.243 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