/// <summary>
        /// Accepts SAML Response, serializes it to XML and signs using the supplied certificate
        /// </summary>
        /// <param name="Response">SAML 2.0 Response</param>
        /// <param name="SigningCert">X509 certificate</param>
        /// <returns>XML Document with computed signature</returns>
        private static XmlDocument SerializeAndSignSAMLResponse(ResponseType Response, X509Certificate2 SigningCert)
        {
            // Set serializer and writers for action
            XmlSerializer responseSerializer = new XmlSerializer(Response.GetType());
            StringWriter  stringWriter       = new StringWriter();
            XmlWriter     responseWriter     = XmlTextWriter.Create(stringWriter, new XmlWriterSettings()
            {
                OmitXmlDeclaration = true, Indent = true, Encoding = Encoding.UTF8
            });

            responseSerializer.Serialize(responseWriter, Response);
            responseWriter.Close();
            XmlDocument xmlResponse = new XmlDocument();

            xmlResponse.LoadXml(stringWriter.ToString());

            // Set the namespace for prettire and more consistent XML
            XmlNamespaceManager ns = new XmlNamespaceManager(xmlResponse.NameTable);

            ns.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");

            CertificateUtility.AppendSignatureToXMLDocument(ref xmlResponse, "#" + ((AssertionType)Response.Items[0]).ID, SigningCert);

            return(xmlResponse);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Accepts SAML Response, serializes it to XML and signs using the supplied certificate
        /// </summary>
        /// <param name="Response">SAML 2.0 Response</param>
        /// <param name="SigningCert">X509 certificate</param>
        /// <returns>XML Document with computed signature</returns>
        private static XmlDocument SerializeAndSignSAMLResponse(ResponseType Response, string partnerSP)
        {
            // Set serializer and writers for action
            XmlSerializer responseSerializer = new XmlSerializer(Response.GetType());
            StringWriter  stringWriter       = new StringWriter();
            XmlWriter     responseWriter     = XmlTextWriter.Create(stringWriter, new XmlWriterSettings()
            {
                OmitXmlDeclaration = true, Indent = true, Encoding = Encoding.UTF8
            });

            responseSerializer.Serialize(responseWriter, Response);
            responseWriter.Close();
            XmlDocument xmlResponse = new XmlDocument();

            xmlResponse.LoadXml(stringWriter.ToString());
            XmlElement elementToEncrypt = xmlResponse.GetElementsByTagName("saml:Assertion")[0] as XmlElement;

            //////////////////////////////////////////////////
            // Create a new instance of the EncryptedXml class
            // and use it to encrypt the XmlElement with the
            // X.509 Certificate.
            //////////////////////////////////////////////////

            EncryptedXml eXml = new EncryptedXml();

            // Encrypt the element.
            var           certificate = SAMLConfiguration.Current.CertificateManager.GetPartnerCertificate(partnerSP);
            EncryptedData edElement   = eXml.Encrypt(elementToEncrypt, certificate);

            XmlElement encryptedAssertion = xmlResponse.CreateElement("saml2", "EncryptedAssertion", "urn:oasis:names:tc:SAML:2.0:assertion");

            EncryptedXml.ReplaceElement(encryptedAssertion, edElement, true);


            ////////////////////////////////////////////////////
            // Replace the element from the original XmlDocument
            // object with the EncryptedData element.
            ////////////////////////////////////////////////////
            xmlResponse.GetElementsByTagName("Response")[0].ReplaceChild(encryptedAssertion, elementToEncrypt);

            //Get the X509 info
            XmlElement issuerSerialElement = xmlResponse.CreateElement("ds", "X509IssuerSerial", SignedXml.XmlDsigNamespaceUrl);
            XmlElement issuerNameElement   = xmlResponse.CreateElement("ds", "X509IssuerName", SignedXml.XmlDsigNamespaceUrl);

            issuerNameElement.AppendChild(xmlResponse.CreateTextNode(certificate.IssuerName.Name));
            issuerSerialElement.AppendChild(issuerNameElement);
            XmlElement serialNumberElement = xmlResponse.CreateElement("ds", "X509SerialNumber", SignedXml.XmlDsigNamespaceUrl);

            serialNumberElement.AppendChild(xmlResponse.CreateTextNode(certificate.SerialNumber));
            issuerSerialElement.AppendChild(serialNumberElement);

            // Set requested namespaces
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["EncryptedData"].Prefix = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["EncryptionMethod"].Prefix           = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["KeyInfo"].Prefix                    = "ds";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["EncryptedKey"].Prefix = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["EncryptionMethod"].Prefix = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["CipherData"].Prefix       = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["xenc:CipherData"]["CipherValue"].Prefix = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["KeyInfo"].Prefix = "ds";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["ds:KeyInfo"]["X509Data"].Prefix = "ds";
            // We don't need this for MagnaCare
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["ds:KeyInfo"]["ds:X509Data"].RemoveChild(xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["ds:KeyInfo"]["ds:X509Data"]["X509Certificate"]);
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["CipherData"].Prefix = "xenc";
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["xenc:CipherData"]["CipherValue"].Prefix = "xenc";

            //Add X509 Issuer Info
            xmlResponse.DocumentElement["saml2:EncryptedAssertion"]["xenc:EncryptedData"]["ds:KeyInfo"]["xenc:EncryptedKey"]["ds:KeyInfo"]["ds:X509Data"].AppendChild(issuerSerialElement);

            // Set the namespace for prettire and more consistent XML
            var ns = new XmlNamespaceManager(xmlResponse.NameTable);

            ns.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
            ns.AddNamespace("xenc", "http://www.w3.org/2001/04/xmlenc#");

            CertificateUtility.AppendSignatureToXMLDocument(ref xmlResponse, "#" + ((AssertionType)Response.Items[0]).ID);

            return(xmlResponse);
        }