예제 #1
0
        /// <summary>
        /// Gets the trusted signers.
        /// </summary>
        /// <param name="keys">The keys.</param>
        /// <param name="identityProvider">The identity provider.</param>
        /// <returns>List of trusted certificate signers.</returns>
        public static IEnumerable <AsymmetricAlgorithm> GetTrustedSigners(ICollection <KeyDescriptor> keys, IdentityProvider identityProvider)
        {
            if (keys == null)
            {
                throw new ArgumentNullException("keys");
            }

            var result = new List <AsymmetricAlgorithm>(keys.Count);

            foreach (var keyDescriptor in keys)
            {
                foreach (KeyInfoClause clause in (KeyInfo)keyDescriptor.KeyInfo)
                {
                    // Check certificate specifications
                    if (clause is KeyInfoX509Data)
                    {
                        var cert = XmlSignatureUtils.GetCertificateFromKeyInfo((KeyInfoX509Data)clause);
                        if (!CertificateSatisfiesSpecifications(identityProvider, cert))
                        {
                            continue;
                        }
                    }

                    var key = XmlSignatureUtils.ExtractKey(clause);
                    result.Add(key);
                }
            }

            return(result);
        }
예제 #2
0
파일: Utility.cs 프로젝트: shawnspeak/SAML2
        /// <summary>
        /// Gets the trusted signers.
        /// </summary>
        /// <param name="keys">The keys.</param>
        /// <param name="identityProvider">The identity provider.</param>
        /// <returns>List of trusted certificate signers.</returns>
        public static IEnumerable <AsymmetricAlgorithm> GetTrustedSigners(ICollection <KeyDescriptor> keys, IdentityProvider identityProvider)
        {
            if (keys == null)
            {
                throw new ArgumentNullException("keys");
            }

            foreach (var item in keys.SelectMany(k => k.KeyInfo.Items))
            {
                var clause = item as KeyInfoClause;

                var x509Data = clause as KeyInfoX509Data ?? (item as KeyInfoClause <KeyInfoX509Data>)?.GetKeyInfoClause();
                if (x509Data != null)
                {
                    var cert = XmlSignatureUtils.GetCertificateFromKeyInfo(x509Data);
                    if (!CertificateSatisfiesSpecifications(identityProvider, cert))
                    {
                        continue;
                    }
                }

                var key = XmlSignatureUtils.ExtractKey(x509Data ?? clause);
                yield return(key);
            }
        }
예제 #3
0
        /// <summary>
        /// Loads an assertion, deserializes it using the <code>Assertion</code> class and returns the
        /// resulting <code>Assertion</code> instance.
        /// </summary>
        public static Saml20Assertion DeserializeToken(string assertionFile)
        {
            FileStream fs = File.OpenRead(assertionFile);

            XmlDocument document = new XmlDocument();

            document.PreserveWhitespace = true;
            document.Load(fs);
            fs.Close();

            Saml20Assertion assertion = new Saml20Assertion(document.DocumentElement, null, false);

            assertion.Validate(DateTime.MinValue);

            List <AsymmetricAlgorithm> result = new List <AsymmetricAlgorithm>(1);

            foreach (KeyInfoClause clause in assertion.GetSignatureKeys())
            {
                AsymmetricAlgorithm key = XmlSignatureUtils.ExtractKey(clause);
                result.Add(key);
            }

            assertion.CheckValid(result);

            return(assertion);
        }
예제 #4
0
        /// <summary>
        /// Gets the trusted signers.
        /// </summary>
        /// <param name="keys">The keys.</param>
        /// <param name="identityProvider">The identity provider.</param>
        /// <returns>List of trusted certificate signers.</returns>
        public static IEnumerable <AsymmetricAlgorithm> GetTrustedSigners(ICollection <KeyDescriptor> keys, IdentityProvider identityProvider)
        {
            if (keys == null)
            {
                throw new ArgumentNullException("keys");
            }

            foreach (var clause in keys.SelectMany(k => k.KeyInfo.Items.AsEnumerable().Where(x => x is X509Data || x is KeyInfoClause)))
            {
                // Check certificate specifications
                if (clause is X509Data)
                {
                    var cert    = new X509Certificate2((byte[])((X509Data)clause).Items.First());
                    var keyInfo = new KeyInfoX509Data(cert, X509IncludeOption.EndCertOnly);

                    //var cert = XmlSignatureUtils.GetCertificateFromKeyInfo((KeyInfoX509Data)clause2);
                    if (!CertificateSatisfiesSpecifications(identityProvider, cert))
                    {
                        continue;
                    }

                    var key = XmlSignatureUtils.ExtractKey(keyInfo);
                    yield return(key);
                }
                else
                {
                    var key = XmlSignatureUtils.ExtractKey((KeyInfoClause)clause);
                    yield return(key);
                }
            }
        }
예제 #5
0
파일: Utility.cs 프로젝트: ahydrax/SAML2
        /// <summary>
        /// Gets the trusted signers.
        /// </summary>
        /// <param name="keys">The keys.</param>
        /// <param name="identityProvider">The identity provider.</param>
        /// <returns>List of trusted certificate signers.</returns>
        public static IEnumerable <AsymmetricAlgorithm> GetTrustedSigners(ICollection <KeyDescriptor> keys, IdentityProvider identityProvider)
        {
            if (keys == null)
            {
                throw new ArgumentNullException(nameof(keys));
            }

            var keyClauses = keys.SelectMany(x => x.KeyInfo.Items).OfType <X509Data>().SelectMany(x => x.Items).OfType <byte[]>().ToList();

            foreach (var keyClause in keyClauses)
            {
                var cert = new X509Certificate2(keyClause);
                if (CertificateSatisfiesSpecifications(identityProvider, cert))
                {
                    yield return(cert.PublicKey.Key);
                }
            }

            foreach (var clause in keys.SelectMany(k => k.KeyInfo.Items.AsEnumerable().OfType <KeyInfoClause>()))
            {
                // Check certificate specifications
                if (clause is KeyInfoX509Data)
                {
                    var cert = XmlSignatureUtils.GetCertificateFromKeyInfo((KeyInfoX509Data)clause);
                    if (!CertificateSatisfiesSpecifications(identityProvider, cert))
                    {
                        continue;
                    }
                }

                var key = XmlSignatureUtils.ExtractKey(clause);
                yield return(key);
            }
        }
예제 #6
0
        /// <summary>
        /// Gets the trusted signers.
        /// </summary>
        /// <param name="keys">The keys.</param>
        /// <param name="identityProvider">The identity provider.</param>
        /// <returns>List of trusted certificate signers.</returns>
        public IEnumerable <AsymmetricAlgorithm> GetTrustedSigners(ICollection <KeyDescriptor> keys, IdentityProvider identityProvider)
        {
            if (keys == null)
            {
                throw new ArgumentNullException("keys");
            }

            foreach (var clause in keys.SelectMany(k => k.KeyInfo.Items.AsEnumerable().Where(x => x is X509Data || x is KeyInfoClause)))
            {
                // Check certificate specifications
                KeyInfoClause keyClause;
                if (clause is X509Data)
                {
                    var cert    = new X509Certificate2((byte[])((X509Data)clause).Items.First());
                    var keyInfo = new KeyInfoX509Data(cert, X509IncludeOption.WholeChain);

                    //TODO: @eByte23: this was old it we must check if there is actually a valid scenario for this
                    //var cert = XmlSignatureUtils.GetCertificateFromKeyInfo((KeyInfoX509Data)clause2);
                    if (!CertificateSatisfiesSpecifications(identityProvider, cert, _logger))
                    {
                        continue;
                    }

                    keyClause = keyInfo;
                }
                else
                {
                    keyClause = (KeyInfoClause)clause;
                }

                yield return(XmlSignatureUtils.ExtractKey(keyClause));
            }
        }
        internal static IEnumerable <AsymmetricAlgorithm> GetTrustedSigners(ICollection <KeyDescriptor> keys, IDPEndPoint ep)
        {
            if (keys == null)
            {
                throw new ArgumentNullException("keys");
            }

            List <AsymmetricAlgorithm> result = new List <AsymmetricAlgorithm>(keys.Count);

            foreach (KeyDescriptor keyDescriptor in keys)
            {
                KeyInfo ki = (KeyInfo)keyDescriptor.KeyInfo;

                foreach (KeyInfoClause clause in ki)
                {
                    if (clause is KeyInfoX509Data)
                    {
                        X509Certificate2 cert = XmlSignatureUtils.GetCertificateFromKeyInfo((KeyInfoX509Data)clause);

                        if (!IsSatisfiedByAllSpecifications(ep, cert))
                        {
                            continue;
                        }
                    }

                    AsymmetricAlgorithm key = XmlSignatureUtils.ExtractKey(clause);
                    result.Add(key);
                }
            }

            return(result);
        }
        /// <summary>
        /// Raised when the SAML 2.0 response parameter has been detected.
        /// </summary>
        /// <param name="url">URL of the page.</param>
        /// <param name="query">The parsed query of the URL.</param>
        /// <param name="fragment">The parsed fragment of the URL.</param>
        /// <param name="formParams">Form parameters, including the 'SAMLResponse'.</param>
        protected override void OnRedirectPageLoaded(Uri url, System.Collections.Generic.IDictionary <string, string> query, System.Collections.Generic.IDictionary <string, string> fragment, IDictionary <string, string> formParams)
        {
            string base64SamlAssertion = formParams.ContainsKey("SAMLResponse") ? formParams ["SAMLResponse"] : string.Empty;

            byte[] xmlSamlAssertionBytes = Convert.FromBase64String(base64SamlAssertion);
            string xmlSamlAssertion      = System.Text.UTF8Encoding.Default.GetString(xmlSamlAssertionBytes);

            XmlDocument xDoc = new XmlDocument();

            xDoc.PreserveWhitespace = true;
            xDoc.LoadXml(xmlSamlAssertion);

            XmlElement responseElement = (XmlElement)xDoc.SelectSingleNode("//*[local-name()='Response']");

#if DEBUG
            Console.WriteLine("{0}", responseElement.OuterXml);
#endif

            XmlElement assertionElement = (XmlElement)xDoc.SelectSingleNode("//*[local-name()='Assertion']");
            if (assertionElement != null)
            {
#if DEBUG
                Console.WriteLine("{0}", assertionElement.OuterXml);
#endif
                Saml20Assertion            samlAssertion  = new Saml20Assertion(assertionElement, null, AssertionProfile.Core, false, false);
                List <AsymmetricAlgorithm> trustedIssuers = new List <AsymmetricAlgorithm>(1);

                foreach (KeyDescriptor key in _idpMetadata.Keys)
                {
                    System.Security.Cryptography.Xml.KeyInfo ki =
                        (System.Security.Cryptography.Xml.KeyInfo)key.KeyInfo;
                    foreach (KeyInfoClause clause in ki)
                    {
                        AsymmetricAlgorithm aa = XmlSignatureUtils.ExtractKey(clause);
                        trustedIssuers.Add(aa);
                    }
                }

                try {
                    samlAssertion.CheckValid(trustedIssuers);
                    SamlAccount sa = new SamlAccount(samlAssertion, responseElement);
                    OnSucceeded(sa);
                }
                catch (Saml20Exception samlEx) {
                    Console.WriteLine(samlEx);
                    OnError(samlEx.Message);
                }
                catch (Exception ex) {
                    Console.WriteLine(ex);
                    OnError(ex.Message);
                }
            }
            else
            {
                OnError("No SAML Assertion Found");;
            }
        }
 public bool CheckSamlMessageSignature(KeyInfo keyInfo)
 {
     foreach (KeyInfoClause clause in keyInfo)
     {
         var key = XmlSignatureUtils.ExtractKey(clause);
         if (key != null && CheckSignature(key))
         {
             return(true);
         }
     }
     return(false);
 }
예제 #10
0
        private static AsymmetricAlgorithm GetTrustedSigner(KeyInfoClause clause, IdentityProvider identityProvider)
        {
            // Check certificate specifications
            if (clause is KeyInfoX509Data)
            {
                var cert = XmlSignatureUtils.GetCertificateFromKeyInfo((KeyInfoX509Data)clause);

                if (!CertificateSatisfiesSpecifications(identityProvider, cert))
                {
                    return(null);
                }
            }

            return(XmlSignatureUtils.ExtractKey(clause));
        }
예제 #11
0
        /// <summary>
        /// Checks the SAML message signature.
        /// </summary>
        /// <param name="keys">The keys to check the signature against.</param>
        /// <returns>True if the signature is valid, else false.</returns>
        public bool CheckSamlMessageSignature(List <KeyDescriptor> keys)
        {
            foreach (var keyDescriptor in keys)
            {
                foreach (KeyInfoClause clause in (KeyInfo)keyDescriptor.KeyInfo)
                {
                    var key = XmlSignatureUtils.ExtractKey(clause);
                    if (key != null && CheckSignature(key))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        /// <summary>
        /// Check the signature of a HTTP-Redirect message using the list of keys.
        /// </summary>
        /// <param name="keys">A list of KeyDescriptor elements. Probably extracted from the metadata describing the IDP that sent the message.</param>
        /// <returns>True, if one of the given keys was able to verify the signature. False in all other cases.</returns>
        public bool VerifySignature(IEnumerable <KeyDescriptor> keys)
        {
            foreach (var keyDescriptor in keys)
            {
                foreach (KeyInfoClause clause in (KeyInfo)keyDescriptor.KeyInfo)
                {
                    var key = XmlSignatureUtils.ExtractKey(clause);
                    if (key != null && CheckSignature(key))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        /// <summary>
        /// Check the signature of a HTTP-Redirect message using the list of keys.
        /// </summary>
        /// <param name="keys">A list of KeyDescriptor elements. Probably extracted from the metadata describing the IDP that sent the message.</param>
        /// <returns>True, if one of the given keys was able to verify the signature. False in all other cases.</returns>
        public bool VerifySignature(IEnumerable <KeyDescriptor> keys)
        {
            foreach (KeyDescriptor keyDescriptor in keys)
            {
                KeyInfo ki = (KeyInfo)keyDescriptor.KeyInfo;
                foreach (KeyInfoClause clause in ki)
                {
                    AsymmetricAlgorithm key = XmlSignatureUtils.ExtractKey(clause);
                    if (key != null && CheckSignature(key))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #14
0
        /// <summary>
        /// Checks the signature of a message received using the redirect binding using the keys found in the
        /// metadata of the federation partner that sent the request.
        /// </summary>
        protected static bool CheckRedirectSignature(HttpRedirectBindingParser parser, Saml20MetadataDocument metadata)
        {
            List <KeyDescriptor> keys = metadata.GetKeys(KeyTypes.signing);

            // Go through the list of signing keys (usually only one) and use it to verify the REDIRECT request.
            foreach (KeyDescriptor key in keys)
            {
                KeyInfo keyinfo = (KeyInfo)key.KeyInfo;
                foreach (KeyInfoClause keyInfoClause in keyinfo)
                {
                    AsymmetricAlgorithm signatureKey = XmlSignatureUtils.ExtractKey(keyInfoClause);
                    if (signatureKey != null && parser.CheckSignature(signatureKey))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
예제 #15
0
        /// <summary>
        /// Gets the trusted signers.
        /// </summary>
        /// <param name="keys">The keys.</param>
        /// <param name="identityProvider">The identity provider.</param>
        /// <returns>List of trusted certificate signers.</returns>
        public static IEnumerable<AsymmetricAlgorithm> GetTrustedSigners(ICollection<KeyDescriptor> keys, IdentityProvider identityProvider)
        {
            if (keys == null) {
                throw new ArgumentNullException("keys");
            }

            foreach (var clause in keys.SelectMany(k => k.KeyInfo.Items.AsEnumerable().Cast<KeyInfoClause>())) {
                // Check certificate specifications
                if (clause is KeyInfoX509Data) {
                    var cert = XmlSignatureUtils.GetCertificateFromKeyInfo((KeyInfoX509Data)clause);
                    if (!CertificateSatisfiesSpecifications(identityProvider, cert)) {
                        continue;
                    }
                }

                var key = XmlSignatureUtils.ExtractKey(clause);
                yield return key;
            }
        }
        /// <summary>
        ///     Checks the signature of the message, using a specific set of keys
        /// </summary>
        /// <param name="keys">The set of keys to check the signature against</param>
        /// <returns></returns>
        public bool CheckSignature(IEnumerable <KeyDescriptor> keys)
        {
            foreach (var keyDescriptor in keys)
            {
                var ki = (KeyInfo)keyDescriptor.KeyInfo;

                foreach (KeyInfoClause clause in ki)
                {
                    var key = XmlSignatureUtils.ExtractKey(clause);

                    if (key != null && XmlSignatureUtils.CheckSignature(_samlMessage, key))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #17
0
        /// <summary>
        /// Loads an assertion, deserializes it using the <code>Assertion</code> class and returns the
        /// resulting <code>Assertion</code> instance.
        /// </summary>
        /// <param name="assertionFile">The assertion file.</param>
        /// <param name="verify">if set to <c>true</c> [verify].</param>
        /// <returns>The <see cref="Saml20Assertion"/>.</returns>
        public static Saml20Assertion DeserializeToken(string assertionFile, bool verify)
        {
            var document = LoadXmlDocument(assertionFile);

            var assertion = new Saml20Assertion(document.DocumentElement, null, false, TestConfiguration.Configuration);

            if (verify)
            {
                var result = new List <AsymmetricAlgorithm>(1);
                foreach (KeyInfoClause clause in assertion.GetSignatureKeys())
                {
                    var key = XmlSignatureUtils.ExtractKey(clause);
                    result.Add(key);
                }

                assertion.CheckValid(result);
            }

            return(assertion);
        }
예제 #18
0
        /// <summary>
        /// Gets the trusted signers.
        /// </summary>
        /// <param name="issuer">The issuer.</param>
        /// <returns>A list of trusted signing certificates.</returns>
        public static IEnumerable <AsymmetricAlgorithm> GetTrustedSigners(string issuer)
        {
            if (issuer == null)
            {
                throw new ArgumentNullException("issuer");
            }

            var config = Saml2Config.GetConfig();

            config.IdentityProviders.Refresh();

            var idpEndpoint = config.IdentityProviders.FirstOrDefault(x => x.Id == issuer);

            if (idpEndpoint == null)
            {
                throw new InvalidOperationException(string.Format("No idp endpoint found for issuer {0}", issuer));
            }

            if (idpEndpoint.Metadata == null)
            {
                throw new InvalidOperationException(string.Format("No metadata found for issuer {0}", issuer));
            }

            if (idpEndpoint.Metadata.Keys == null)
            {
                throw new InvalidOperationException(string.Format("No key descriptors found in metadata found for issuer {0}", issuer));
            }

            var result = new List <AsymmetricAlgorithm>(1);

            foreach (var key in idpEndpoint.Metadata.Keys)
            {
                foreach (KeyInfoClause clause in (KeyInfo)key.KeyInfo)
                {
                    var aa = XmlSignatureUtils.ExtractKey(clause);
                    result.Add(aa);
                }
            }

            return(result);
        }
예제 #19
0
        public static IEnumerable <AsymmetricAlgorithm> GetTrustedSigners(string issuer)
        {
            if (issuer == null)
            {
                throw new ArgumentNullException("issuer");
            }

            SAML20FederationConfig config = ConfigurationReader.GetConfig <SAML20FederationConfig>();

            config.Endpoints.Refresh();
            IDPEndPoint idpEndpoint = config.FindEndPoint(issuer);

            if (idpEndpoint == null)
            {
                throw new InvalidOperationException(String.Format("No idp endpoint found for issuer {0}", issuer));
            }

            if (idpEndpoint.metadata == null)
            {
                throw new InvalidOperationException(String.Format("No metadata found for issuer {0}", issuer));
            }

            if (idpEndpoint.metadata.Keys == null)
            {
                throw new InvalidOperationException(String.Format("No key descriptors found in metadata found for issuer {0}", issuer));
            }

            List <AsymmetricAlgorithm> result = new List <AsymmetricAlgorithm>(1);

            foreach (KeyDescriptor key in idpEndpoint.metadata.Keys)
            {
                KeyInfo ki = (KeyInfo)key.KeyInfo;
                foreach (KeyInfoClause clause in ki)
                {
                    AsymmetricAlgorithm aa = XmlSignatureUtils.ExtractKey(clause);
                    result.Add(aa);
                }
            }

            return(result);
        }
예제 #20
0
        /// <summary>
        /// Gets the trusted signers.
        /// </summary>
        /// <param name="issuer">The issuer.</param>
        /// <returns>A list of trusted signing certificates.</returns>
        public static IEnumerable <AsymmetricAlgorithm> GetTrustedSigners(string issuer)
        {
            if (issuer == null)
            {
                throw new ArgumentNullException(nameof(issuer));
            }

            // TODO: Mock out a config for this test
            SAML2.Config.Saml2Configuration config = TestConfiguration.Configuration; // Saml2Config.GetConfig();

            var idpEndpoint = config.IdentityProvidersSource.GetById(issuer);

            if (idpEndpoint == null)
            {
                throw new InvalidOperationException(string.Format("No idp endpoint found for issuer {0}", issuer));
            }

            if (idpEndpoint.Metadata == null)
            {
                throw new InvalidOperationException(string.Format("No metadata found for issuer {0}", issuer));
            }

            if (idpEndpoint.Metadata.Keys == null)
            {
                throw new InvalidOperationException(string.Format("No key descriptors found in metadata found for issuer {0}", issuer));
            }

            var result = new List <AsymmetricAlgorithm>(1);

            foreach (var key in idpEndpoint.Metadata.Keys)
            {
                foreach (KeyInfoClause clause in (KeyInfo)key.KeyInfo)
                {
                    var aa = XmlSignatureUtils.ExtractKey(clause);
                    result.Add(aa);
                }
            }

            return(result);
        }
예제 #21
0
        private void CreateAssertionResponse(User user)
        {
            string entityId = request.Issuer.Value;
            Saml20MetadataDocument metadataDocument = IDPConfig.GetServiceProviderMetadata(entityId);
            IDPEndPointElement     endpoint         =
                metadataDocument.AssertionConsumerServiceEndpoints().Find(delegate(IDPEndPointElement e) { return(e.Binding == SAMLBinding.POST); });

            if (endpoint == null)
            {
                Context.Response.Write(string.Format("'{0}' does not have a SSO endpoint that supports the POST binding.", entityId));
                Context.Response.End();
                return;
            }

            UserSessionsHandler.AddLoggedInSession(entityId);

            Response response = new Response();

            response.Destination             = endpoint.Url;
            response.InResponseTo            = request.ID;
            response.Status                  = new Status();
            response.Status.StatusCode       = new StatusCode();
            response.Status.StatusCode.Value = Saml20Constants.StatusCodes.Success;

            var       nameIdFormat = metadataDocument.Entity.Items.OfType <SPSSODescriptor>().SingleOrDefault()?.NameIDFormat.SingleOrDefault() ?? Saml20Constants.NameIdentifierFormats.Persistent;
            Assertion assertion    = CreateAssertion(user, entityId, nameIdFormat);

            var signatureProvider = SignatureProviderFactory.CreateFromShaHashingAlgorithmName(ShaHashingAlgorithm.SHA256);
            EncryptedAssertion encryptedAssertion = null;

            var keyDescriptors = metadataDocument.Keys.Where(x => x.use == KeyTypes.encryption);

            if (keyDescriptors.Any())
            {
                foreach (KeyDescriptor keyDescriptor in keyDescriptors)
                {
                    KeyInfo ki = (KeyInfo)keyDescriptor.KeyInfo;

                    foreach (KeyInfoClause clause in ki)
                    {
                        if (clause is KeyInfoX509Data)
                        {
                            X509Certificate2 cert = XmlSignatureUtils.GetCertificateFromKeyInfo((KeyInfoX509Data)clause);

                            var    spec = new DefaultCertificateSpecification();
                            string error;
                            if (spec.IsSatisfiedBy(cert, out error))
                            {
                                AsymmetricAlgorithm key = XmlSignatureUtils.ExtractKey(clause);
                                AssertionEncryptionUtility.AssertionEncryptionUtility encryptedAssertionUtil = new AssertionEncryptionUtility.AssertionEncryptionUtility((RSA)key, assertion);

                                // Sign the assertion inside the response message.
                                signatureProvider.SignAssertion(encryptedAssertionUtil.Assertion, assertion.ID, IDPConfig.IDPCertificate);

                                encryptedAssertionUtil.Encrypt();
                                encryptedAssertion = Serialization.DeserializeFromXmlString <EncryptedAssertion>(encryptedAssertionUtil.EncryptedAssertion.OuterXml);
                                break;
                            }
                        }
                    }
                    if (encryptedAssertion != null)
                    {
                        break;
                    }
                }

                if (encryptedAssertion == null)
                {
                    throw new Exception("Could not encrypt. No valid certificates found.");
                }
            }

            if (encryptedAssertion != null)
            {
                response.Items = new object[] { encryptedAssertion };
            }
            else
            {
                response.Items = new object[] { assertion };
            }

            // Serialize the response.
            XmlDocument responseDoc = new XmlDocument();

            responseDoc.XmlResolver        = null;
            responseDoc.PreserveWhitespace = true;
            responseDoc.LoadXml(Serialization.SerializeToXmlString(response));

            if (encryptedAssertion == null)
            {
                // Sign the assertion inside the response message.
                signatureProvider.SignAssertion(responseDoc, assertion.ID, IDPConfig.IDPCertificate);
            }

            HttpPostBindingBuilder builder = new HttpPostBindingBuilder(endpoint);

            builder.Action = SAMLAction.SAMLResponse;

            builder.Response = responseDoc.OuterXml;

            builder.GetPage().ProcessRequest(Context);
            Context.Response.End();
        }