Our IdP is a Salesforce.com org. The SP is a third party .Net application. During development, the 3rd party reported that they're unable to validate the SAML response sent.
We decided to try validating on our end using ComponentSpace to validate the SAML response. Below is what we tried:
// Load the certificate from the file: certInFile
// Load the SAML in an XMLElement: samlXml
// Retrieve the certificate from the SAML: certInSaml
Console.WriteLine("SAML is valid ? " + SAMLResponse.IsValid(samlXml));
Console.WriteLine("Is SAML signed? " + SAMLMessageSignature.IsSigned(samlXml));
Console.WriteLine("Certificate found in SAML is same as certificate file? " + certInFile.Equals(certInSaml));
Console.WriteLine("Validated SAML with certificate found in SAML" + SAMLMessageSignature.Verify(samlXml, certInSaml));
Console.WriteLine("Validated SAML with certificate file" + SAMLMessageSignature.Verify(samlXml, certInFile));
I'm getting true for everything above, except the last two. So:
From 3,4 can we conclude that Salesforce is signing but with a different certificate but sending the wrong public key in the response?!
Edit: Sample SAML is here http://pastebin.com/J8FTxnhJ
What am I missing?
An XML signature verification fails either because the XML has been modified after signing or the wrong certificate is being used to verify the signature. The most likely scenario is that the wrong certificate is being used.
Salesforce signs the SAML response using their private key. Using the Salesforce admin console you can download the corresponding public key/certificate which should be used to perform the signature verification.
When calling SAMLMessageSignature.Verify
, you can specify the X509Certificate
to use to perform the verification which is typically what you should do.
However, the base-64 encoded X.509 certificate is also embedded in the XML signature. You can use this embedded certificate to check whether the signature verifies.
To do this, don't pass in an X509Certificate to SAMLMessageSignature.Verify
.
For example: SAMLMessageSignature.Verify(samlXml, null);
If that works but specifying a certificate down't work then this confirms that the wrong certificate is being used.
You can call SAMLMessageSignature.GetCertificate
to retrieve the X.509 certificate from the XML signature to compare it with the certificate being used.
Also, as a side note, XML signatures apply to XML. They cannot be directly verified using the base-64 encoded SAML response sent in the HTTP Post data. The post data must be decoded to XML prior to attempting to verify the XML signature.