I am using ITfoxtec.Identity.Saml2.MvcCore
SAML2 SSO with an IBM commercial IdP server product. <SamlResponse>
has a signed <Assertion>
element, with no other signatures or encryption.
SSO authentication works as expected if I skip the Saml2PostBinding.Unbind
call. However, project requirements and enterprise policies dictate that signatures must be verified.
When making the Saml2PostBinding.Unbind
call, I can step through the ITfoxtec source code for the latest package release (4.10.4), and see it pass all the signature detection checks, correctly detect the signing cert, and detect and apply the signature algorithm (http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
) and the correct canonicalisation (http://www.w3.org/2001/10/xml-exc-c14n#
). Everything proceeds as expected until it executes this line of code:
return CheckSignature(Saml2Signer.Certificate.GetRSAPublicKey());
which is calling into standard dotnet crypto routines. It fails this call by returning false. Turning on symbol server source debugging, it is failing on this section of code in System.Security.Cryptography.Xml.SignedXml.CheckDigestedReferences()
:
try
{
calculatedHash = digestedReference.CalculateHashValue(_containingDocument, m_signature.ReferencedItems);
}
catch (CryptoSignedXmlRecursionException)
{
SignedXmlDebugLog.LogSignedXmlRecursionLimit(this, digestedReference);
return false;
}
SignedXmlDebugLog.LogVerifyReferenceHash(this, digestedReference, calculatedHash, digestedReference.DigestValue);
if (!CryptographicEquals(calculatedHash, digestedReference.DigestValue))
{
return false;
}
because the calculatedHash
does not equal the digestedReference.DigestValue
.
Signing cert, intermediate certs and root cert are all valid, and explictly imported and trusted in the cert store on the repro machine (Windows 10 Business 21H2, 19044.3086 build, Windows Feature Experience Pack 1000.19041.1000.0).
The kicker is that the failing <SamlResponse>
passes signature validation in the onelogin Validate SAML Response tool at https://www.samltool.com/validate_response.php. After it passes, I can even make onelogin fail it by changing a single character inside the <Assertion>
element.
On the face of it, I would also not expect a mature IBM commercial IdP server product to misapply signatures.
What I tried: I tried debugging the ITfoxTec code and the dotnet source code. I tried verifying the signature in an external tool.
What I expected: I expected the signature to verify inside both ITfoxTec and the external tool.
What resulted: What resulted was that the signature verified in the external tool but not inside ITfoxTec.
What .NET version are you running?
I'm wondering if the problem is related to issue #156, do you see the same problem in version 4.8.2?