locked
Verify signature on SAML assertion RRS feed

  • Question

  • I've already asked this question on StackOverflow (http://stackoverflow.com/questions/25394137/verify-signature-on-saml-assertion), but I'm hoping to get a better response here. I'm trying to validate some SAML that looks like this:

    <samlp2:Response Destination="http://www.testhabaGoba.com" ID="ResponseId_934151edfe060ceec3067670c2f0f1ea" IssueInstant="2013-09-24T14:33:29.507Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp2="urn:oasis:names:tc:SAML:2.0:protocol">
        ...
        <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            ...
        </ds:Signature>
        ...
        <saml2:Assertion ID="SamlAssertion-05fd8af7f2c9972e69cdbca612d3f3b8" IssueInstant="2013-09-24T14:33:29.496Z" Version="2.0" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
            ...
            <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                ...
            </ds:Signature>
            ...
        </saml2:Assertion>
    </samlp2:Response>

    The signature on the response always passes, but the signature on the assertion always fails. Even when I use a SAML that doesn't sign the response the assertion signature fails. Here's a condensed version of the code I'm using:

    foreach (XmlElement node in xmlDoc.SelectNodes("//*[local-name()='Signature']"))
    {// Verify this Signature block
        SignedXml signedXml = new SignedXml(node.ParentNode as XmlElement);
        signedXml.LoadXml(node);
        KeyInfoX509Data x509Data = signedXml.Signature.KeyInfo.OfType<KeyInfoX509Data>().First();
    
        // Verify certificate
        X509Certificate2 cert = x509Data.Certificates[0] as X509Certificate2;
        log.Info(string.Format("Cert s/n: {0}", cert.SerialNumber));
        VerifyX509Chain(cert);// Custom method
    
        // Check for approval
        X509Store store = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine);
        store.Open(OpenFlags.ReadOnly);
        X509Certificate2Collection collection = store.Certificates.Find(X509FindType.FindBySerialNumber, cert.SerialNumber, true);
        Debug.Assert(collection.Count == 1);// Standing in for brevity
    
        // Verify signature
        signedXml.CheckSignature(cert, true);
    }
    Everything works except the CheckSignature method. It's the only thing that fails and it always fails the SAML assertion. What am I doing wrong?

    • Moved by Barry Wang Thursday, August 21, 2014 8:24 AM
    Wednesday, August 20, 2014 4:14 PM

Answers

  • Found the answer. See the explanation at StackOverflow (http://stackoverflow.com/questions/25394137/verify-signature-on-saml-assertion/25436812#25436812). Here's the updated snippet of code:

    foreach (XmlElement node in xmlDoc.SelectNodes("//*[local-name()='Signature']"))
    {// Verify this Signature block
        SignedXml signedXml = new SignedXml(node.ParentNode as XmlElement);
        signedXml.LoadXml(node);
        KeyInfoX509Data x509Data = signedXml.Signature.KeyInfo.OfType<KeyInfoX509Data>().First();
    
        // *** ADDED CODE ***
        if (!node.ParentNode.Equals(node.OwnerDocument.DocumentElement))
        {
            node.ParentNode.RemoveChild(node);
            // This line ^^^ is apparently optional, but it makes me feel better
            node.OwnerDocument.DocumentElement.AppendChild(node);
        }
    
        // Verify certificate
        ...

    Thursday, August 21, 2014 10:18 PM

All replies

  • Hello Matthew T. Ricks,

    Personally after reading your post I don't think this issue is related to this forum "Discuss and ask questions about the C# programming language, IDE, libraries, samples, and tools."

    The problem is due to SAML assertion fail and I read something like this http://docs.oracle.com/cd/E21455_01/common/tutorials/authn_saml_xml_sig.html to konw what is SAML and how it works. I will recommend you consult SAML related forum to ask this question.

    Regards,



    Barry
    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, August 21, 2014 8:24 AM
  • Thank you, but I know the assertion/SAML is valid. I need to know how to figure that out for myself using C#. 
    Thursday, August 21, 2014 6:54 PM
  • Found the answer. See the explanation at StackOverflow (http://stackoverflow.com/questions/25394137/verify-signature-on-saml-assertion/25436812#25436812). Here's the updated snippet of code:

    foreach (XmlElement node in xmlDoc.SelectNodes("//*[local-name()='Signature']"))
    {// Verify this Signature block
        SignedXml signedXml = new SignedXml(node.ParentNode as XmlElement);
        signedXml.LoadXml(node);
        KeyInfoX509Data x509Data = signedXml.Signature.KeyInfo.OfType<KeyInfoX509Data>().First();
    
        // *** ADDED CODE ***
        if (!node.ParentNode.Equals(node.OwnerDocument.DocumentElement))
        {
            node.ParentNode.RemoveChild(node);
            // This line ^^^ is apparently optional, but it makes me feel better
            node.OwnerDocument.DocumentElement.AppendChild(node);
        }
    
        // Verify certificate
        ...

    Thursday, August 21, 2014 10:18 PM