private static Saml20EncryptedAssertion GetDecryptedAssertion(XmlElement elem)
        {
            Saml20EncryptedAssertion decryptedAssertion = new Saml20EncryptedAssertion((RSA)FederationConfig.GetConfig().SigningCertificate.GetCertificate().PrivateKey);

            decryptedAssertion.LoadXml(elem);
            decryptedAssertion.Decrypt();
            return(decryptedAssertion);
        }
        /// <summary>
        /// Decrypts an encrypted assertion if any of the configured certificates contains the correct
        /// private key to use for decrypting. If no configured certificates can be used to decrypt the
        /// encrypted assertion, the first exception will be rethrown.
        /// </summary>
        /// <param name="elem"></param>
        /// <returns></returns>
        private static Saml20EncryptedAssertion GetDecryptedAssertion(XmlElement elem)
        {
            var tryDecryptAssertion = new Func <X509Certificate2, Saml20EncryptedAssertion>((certificate) =>
            {
                Saml20EncryptedAssertion decryptedAssertion = new Saml20EncryptedAssertion((RSA)certificate.PrivateKey);
                decryptedAssertion.LoadXml(elem);
                decryptedAssertion.Decrypt();
                return(decryptedAssertion);
            });

            var allValidX509Certificates = new List <X509Certificate2>();

            foreach (var certificate in FederationConfig.GetConfig().SigningCertificates)
            {
                var x509Certificates = certificate.GetAllValidX509Certificates();
                if (x509Certificates == null)
                {
                    continue;
                }

                foreach (var x in x509Certificates)
                {
                    allValidX509Certificates.Add(x);
                }
            }

            foreach (var certificate in allValidX509Certificates)
            {
                try
                {
                    return(tryDecryptAssertion(certificate));
                }
                catch (Exception)
                {
                    foreach (var certificate2 in allValidX509Certificates)
                    {
                        if (certificate != certificate2)
                        {
                            try
                            {
                                return(tryDecryptAssertion(certificate2));
                            }
                            catch (Exception)
                            {
                                continue;
                            }
                        }
                    }

                    throw;
                }
            }

            var msg = $"Found no valid certificate configured in the certificate configuration. Make sure at least one valid certificate is configured.";

            throw new ConfigurationErrorsException(msg);
        }
        /// <summary>
        /// Decrypts an assertion we received from "fælles-offentlige brugerstyring".
        /// </summary>
        private static void DecryptFOBSAssertion(string file)
        {
            string assertionBase64 = File.ReadAllText(file);

            byte[] assertionBytes = Convert.FromBase64String(assertionBase64);

            XmlDocument doc = new XmlDocument();

            doc.PreserveWhitespace = true;
            doc.Load(new MemoryStream(assertionBytes));

            XmlNodeList encryptedList =
                doc.GetElementsByTagName(EncryptedAssertion.ELEMENT_NAME, Saml20Constants.ASSERTION);

            Assert.That(encryptedList.Count == 1);

            // Do some mock configuration.
            FederationConfig config = FederationConfig.GetConfig();

            config.AllowedAudienceUris.Audiences.Add("https://saml.safewhere.net");

            SAML20FederationConfig descr = SAML20FederationConfig.GetConfig();

            descr.Endpoints.MetadataLocation = @"Saml20\Protocol\MetadataDocs\FOBS"; // Set it manually.
            Assert.That(Directory.Exists(descr.Endpoints.MetadataLocation));

            X509Certificate2         cert   = new X509Certificate2(@"Saml20\Certificates\SafewhereTest_SFS.pfx", "test1234");
            Saml20EncryptedAssertion encass =
                new Saml20EncryptedAssertion((RSA)cert.PrivateKey);

            encass.LoadXml((XmlElement)encryptedList[0]);
            encass.Decrypt();

            // Retrieve metadata
            Saml20Assertion assertion = new Saml20Assertion(encass.Assertion.DocumentElement, null, false);

            IDPEndPoint endp = descr.FindEndPoint(assertion.Issuer);

            Assert.IsNotNull(endp, "Endpoint not found");
            Assert.IsNotNull(endp.metadata, "Metadata not found");

            try
            {
                assertion.CheckValid(AssertionUtil.GetTrustedSigners(assertion.Issuer));
                Assert.Fail("Verification should fail. Token does not include its signing key.");
            } catch (InvalidOperationException)
            {}

            Assert.IsNull(assertion.SigningKey, "Signing key is already present on assertion. Modify test.");
            IEnumerable <string> validationFailures;

            Assert.That(assertion.CheckSignature(Saml20SignonHandler.GetTrustedSigners(endp.metadata.GetKeys(KeyTypes.signing), endp, out validationFailures)));
            Assert.IsNotNull(assertion.SigningKey, "Signing key was not set on assertion instance.");
        }
Example #4
0
        /// <summary>
        /// Gets the decrypted assertion.
        /// </summary>
        /// <param name="elem">The elem.</param>
        /// <returns>The decrypted <see cref="Saml20EncryptedAssertion"/>.</returns>
        public static Saml20EncryptedAssertion GetDecryptedAssertion(XmlElement elem, Saml2Configuration config)
        {
            logger.Debug(TraceMessages.EncryptedAssertionDecrypting);

            var decryptedAssertion = new Saml20EncryptedAssertion((RSA)config.ServiceProvider.SigningCertificate.PrivateKey);
            decryptedAssertion.LoadXml(elem);
            decryptedAssertion.Decrypt();

            logger.DebugFormat(TraceMessages.EncryptedAssertionDecrypted, decryptedAssertion.Assertion.DocumentElement.OuterXml);

            return decryptedAssertion;
        }
Example #5
0
        /// <summary>
        /// Gets the decrypted assertion.
        /// </summary>
        /// <param name="elem">The elem.</param>
        /// <returns>The decrypted <see cref="Saml20EncryptedAssertion"/>.</returns>
        private static Saml20EncryptedAssertion GetDecryptedAssertion(XmlElement elem)
        {
            Logger.Debug(TraceMessages.EncryptedAssertionDecrypting);

            var decryptedAssertion = new Saml20EncryptedAssertion((RSA)Saml2Config.Current.ServiceProvider.SigningCertificate.GetCertificate().PrivateKey);

            decryptedAssertion.LoadXml(elem);
            decryptedAssertion.Decrypt();

            Logger.DebugFormat(TraceMessages.EncryptedAssertionDecrypted, decryptedAssertion.Assertion.DocumentElement.OuterXml);

            return(decryptedAssertion);
        }
Example #6
0
        public void TestAlgorithmConfiguration_02()
        {
            Saml20EncryptedAssertion encryptedAssertion = new Saml20EncryptedAssertion();

            encryptedAssertion.SessionKeyAlgorithm = EncryptedXml.XmlEncAES128Url;
            encryptedAssertion.Assertion           = AssertionUtil.GetTestAssertion_01();

            X509Certificate2 cert = new X509Certificate2(@"Saml20\Certificates\sts_dev_certificate.pfx", "test1234");

            encryptedAssertion.TransportKey = (RSA)cert.PublicKey.Key;

            encryptedAssertion.Encrypt();
            XmlDocument encryptedAssertionXML = encryptedAssertion.GetXml();

            Assert.IsNotNull(encryptedAssertionXML);

            // Verify that the EncryptionMethod element is set correctly.
            XmlNodeList list =
                encryptedAssertionXML.GetElementsByTagName(dk.nita.saml20.Schema.XEnc.EncryptedData.ELEMENT_NAME,
                                                           Saml20Constants.XENC);

            Assert.AreEqual(1, list.Count);
            XmlElement el = (XmlElement)list[0];

            // Go through the children and look for the EncryptionMethod element, and verify its algorithm attribute.
            bool encryptionMethodFound = false;

            foreach (XmlNode node in el.ChildNodes)
            {
                if (node.LocalName == dk.nita.saml20.Schema.XEnc.EncryptionMethod.ELEMENT_NAME &&
                    node.NamespaceURI == Saml20Constants.XENC)
                {
                    el = (XmlElement)node;
                    Assert.AreEqual(EncryptedXml.XmlEncAES128Url, el.GetAttribute("Algorithm"));
                    encryptionMethodFound = true;
                }
            }
            Assert.That(encryptionMethodFound, "Unable to find EncryptionMethod element in EncryptedData.");

            // Now decrypt the assertion, and verify that it recognizes the Algorithm used.
            Saml20EncryptedAssertion decrypter = new Saml20EncryptedAssertion((RSA)cert.PrivateKey);

            Assert.IsNull(decrypter.Assertion);
            decrypter.LoadXml(encryptedAssertionXML.DocumentElement);
            // Set a wrong algorithm and make sure that the class gets it algorithm info from the assertion itself.
            decrypter.SessionKeyAlgorithm = EncryptedXml.XmlEncTripleDESUrl;
            decrypter.Decrypt();
            // Verify that the class has discovered the correct algorithm and set the SessionKeyAlgorithm property accordingly.
            Assert.AreEqual(EncryptedXml.XmlEncAES128Url, decrypter.SessionKeyAlgorithm);
            Assert.IsNotNull(decrypter.Assertion);
        }
            //[ExpectedException(typeof(Saml20Exception), ExpectedMessage = "Assertion is no longer valid.")]
            public void CanDecryptFOBSAssertion()
            {
                // Arrange
                var doc           = AssertionUtil.LoadBase64EncodedXmlDocument(@"Assertions\fobs-assertion2");
                var encryptedList = doc.GetElementsByTagName(EncryptedAssertion.ElementName, Saml20Constants.Assertion);

                // Do some mock configuration.
                var idpSource = new IdentityProviders();
                var config    = new Saml2Configuration
                {
                    AllowedAudienceUris     = new System.Collections.Generic.List <Uri>(),
                    IdentityProvidersSource = idpSource
                };

                config.AllowedAudienceUris.Add(new Uri("https://saml.safewhere.net"));
                idpSource.AddByMetadataDirectory(@"Protocol\MetadataDocs\FOBS"); // Set it manually.

                var cert = new X509Certificate2(@"Certificates\SafewhereTest_SFS.pfx", "test1234");
                var encryptedAssertion = new Saml20EncryptedAssertion((RSA)cert.PrivateKey);

                encryptedAssertion.LoadXml((XmlElement)encryptedList[0]);

                // Act
                encryptedAssertion.Decrypt();

                // Retrieve metadata
                var assertion = new Saml20Assertion(encryptedAssertion.Assertion.DocumentElement, null, false, TestConfiguration.Configuration);
                var endp      = config.IdentityProvidersSource.GetById(assertion.Issuer);

                // Assert
                Assert.That(encryptedList.Count == 1);
                Assert.IsNotNull(endp, "Endpoint not found");
                Assert.IsNotNull(endp.Metadata, "Metadata not found");

                try
                {
                    assertion.CheckValid(AssertionUtil.GetTrustedSigners(assertion.Issuer));
                    Assert.Fail("Verification should fail. Token does not include its signing key.");
                }
                catch (InvalidOperationException)
                {
                }

                Assert.IsNull(assertion.SigningKey, "Signing key is already present on assertion. Modify test.");
                //Assert.IsTrue("We have tested this next test" == "");
                //Assert.That(assertion.CheckSignature(Saml20SignonHandler.GetTrustedSigners(endp.Metadata.GetKeys(KeyTypes.Signing), endp)));
                //Assert.IsNotNull(assertion.SigningKey, "Signing key was not set on assertion instance.");
            }
        public void CanEncryptAssertionFull()
        {
            // Arrange
            var encryptedAssertion = new Saml20EncryptedAssertion
            {
                SessionKeyAlgorithm = EncryptedXml.XmlEncAES128Url,
                Assertion           = AssertionUtil.GetTestAssertion()
            };

            var cert = new X509Certificate2(TestContext.CurrentContext.TestDirectory + @"\Certificates\sts_dev_certificate.pfx", "test1234");

            encryptedAssertion.TransportKey = (RSA)cert.PublicKey.Key;

            // Act
            encryptedAssertion.Encrypt();
            var encryptedAssertionXml = encryptedAssertion.GetXml();

            // Now decrypt the assertion, and verify that it recognizes the Algorithm used.
            var decrypter = new Saml20EncryptedAssertion((RSA)cert.PrivateKey);

            decrypter.LoadXml(encryptedAssertionXml.DocumentElement);

            // Set a wrong algorithm and make sure that the class gets it algorithm info from the assertion itself.
            decrypter.SessionKeyAlgorithm = EncryptedXml.XmlEncTripleDESUrl;
            decrypter.Decrypt();

            // Assert
            // Go through the children and look for the EncryptionMethod element, and verify its algorithm attribute.
            var encryptionMethodFound = false;

            foreach (XmlNode node in encryptedAssertionXml.GetElementsByTagName(Schema.XEnc.EncryptedData.ElementName, Saml20Constants.Xenc)[0].ChildNodes)
            {
                if (node.LocalName == Schema.XEnc.EncryptionMethod.ElementName && node.NamespaceURI == Saml20Constants.Xenc)
                {
                    var element = (XmlElement)node;
                    Assert.AreEqual(EncryptedXml.XmlEncAES128Url, element.GetAttribute("Algorithm"));
                    encryptionMethodFound = true;
                }
            }

            Assert.That(encryptionMethodFound, "Unable to find EncryptionMethod element in EncryptedData.");

            // Verify that the class has discovered the correct algorithm and set the SessionKeyAlgorithm property accordingly.
            Assert.AreEqual(EncryptedXml.XmlEncAES128Url, decrypter.SessionKeyAlgorithm);
            Assert.IsNotNull(decrypter.Assertion);
        }
            public void CanDecryptFOBSAssertion()
            {
                // Arrange
                var doc           = AssertionUtil.LoadBase64EncodedXmlDocument(@"Assertions\fobs-assertion2");
                var encryptedList = doc.GetElementsByTagName(EncryptedAssertion.ElementName, Saml20Constants.Assertion);

                // Do some mock configuration.
                var config = Saml2Config.GetConfig();

                config.AllowedAudienceUris.Add(new AudienceUriElement {
                    Uri = "https://saml.safewhere.net"
                });
                config.IdentityProviders.MetadataLocation = @"Protocol\MetadataDocs\FOBS"; // Set it manually.
                Assert.That(Directory.Exists(config.IdentityProviders.MetadataLocation));

                var cert = new X509Certificate2(@"Certificates\SafewhereTest_SFS.pfx", "test1234");
                var encryptedAssertion = new Saml20EncryptedAssertion((RSA)cert.PrivateKey);

                encryptedAssertion.LoadXml((XmlElement)encryptedList[0]);

                // Act
                encryptedAssertion.Decrypt();

                // Retrieve metadata
                var assertion = new Saml20Assertion(encryptedAssertion.Assertion.DocumentElement, null, false);
                var endp      = config.IdentityProviders.FirstOrDefault(x => x.Id == assertion.Issuer);

                // Assert
                Assert.That(encryptedList.Count == 1);
                Assert.IsNotNull(endp, "Endpoint not found");
                Assert.IsNotNull(endp.Metadata, "Metadata not found");

                try
                {
                    assertion.CheckValid(AssertionUtil.GetTrustedSigners(assertion.Issuer));
                    Assert.Fail("Verification should fail. Token does not include its signing key.");
                }
                catch (InvalidOperationException)
                {
                }

                Assert.IsNull(assertion.SigningKey, "Signing key is already present on assertion. Modify test.");
                Assert.That(assertion.CheckSignature(Saml20SignonHandler.GetTrustedSigners(endp.Metadata.GetKeys(KeyTypes.Signing), endp)));
                Assert.IsNotNull(assertion.SigningKey, "Signing key was not set on assertion instance.");
            }
        public void CanEncryptAssertionFull()
        {
            // Arrange
            var encryptedAssertion = new Saml20EncryptedAssertion
                                         {
                                             SessionKeyAlgorithm = EncryptedXml.XmlEncAES128Url,
                                             Assertion = AssertionUtil.GetTestAssertion()
                                         };

            var cert = new X509Certificate2(@"Certificates\sts_dev_certificate.pfx", "test1234");
            encryptedAssertion.TransportKey = (RSA)cert.PublicKey.Key;

            // Act
            encryptedAssertion.Encrypt();
            var encryptedAssertionXml = encryptedAssertion.GetXml();

            // Now decrypt the assertion, and verify that it recognizes the Algorithm used.
            var decrypter = new Saml20EncryptedAssertion((RSA)cert.PrivateKey);
            decrypter.LoadXml(encryptedAssertionXml.DocumentElement);

            // Set a wrong algorithm and make sure that the class gets it algorithm info from the assertion itself.
            decrypter.SessionKeyAlgorithm = EncryptedXml.XmlEncTripleDESUrl;
            decrypter.Decrypt();

            // Assert
            // Go through the children and look for the EncryptionMethod element, and verify its algorithm attribute.
            var encryptionMethodFound = false;
            foreach (XmlNode node in encryptedAssertionXml.GetElementsByTagName(Schema.XEnc.EncryptedData.ElementName, Saml20Constants.Xenc)[0].ChildNodes)
            {
                if (node.LocalName == Schema.XEnc.EncryptionMethod.ElementName && node.NamespaceURI == Saml20Constants.Xenc)
                {
                    var element = (XmlElement)node;
                    Assert.AreEqual(EncryptedXml.XmlEncAES128Url, element.GetAttribute("Algorithm"));
                    encryptionMethodFound = true;
                }
            }

            Assert.That(encryptionMethodFound, "Unable to find EncryptionMethod element in EncryptedData.");

            // Verify that the class has discovered the correct algorithm and set the SessionKeyAlgorithm property accordingly.
            Assert.AreEqual(EncryptedXml.XmlEncAES128Url, decrypter.SessionKeyAlgorithm);
            Assert.IsNotNull(decrypter.Assertion);
        }
            public void CanDecryptFOBSAssertion()
            {
                // Arrange
                var doc           = AssertionUtil.LoadBase64EncodedXmlDocument(TestContext.CurrentContext.TestDirectory + @"\Assertions\fobs-assertion2");
                var encryptedList = doc.GetElementsByTagName(EncryptedAssertion.ElementName, Saml20Constants.Assertion);

                // Do some mock configuration.
                var config = Saml2Config.Current;

                config.AllowedAudienceUris.Add("https://saml.safewhere.net");
                config.IdentityProviders.MetadataLocation = TestContext.CurrentContext.TestDirectory + @"\Protocol\MetadataDocs\FOBS"; // Set it manually.
                config.IdentityProviders.Refresh();

                var cert = new X509Certificate2(TestContext.CurrentContext.TestDirectory + @"\Certificates\SafewhereTest_SFS.pfx", "test1234");
                var encryptedAssertion = new Saml20EncryptedAssertion((RSA)cert.PrivateKey);

                encryptedAssertion.LoadXml((XmlElement)encryptedList[0]);

                // Act
                encryptedAssertion.Decrypt();

                // Retrieve metadata
                var assertion = new Saml20Assertion(encryptedAssertion.Assertion.DocumentElement, null, false);
                var endp      = config.IdentityProviders.FirstOrDefault(x => x.Id == assertion.Issuer);

                // Assert
                Assert.That(encryptedList.Count == 1);
                Assert.IsNotNull(endp, "Endpoint not found");
                Assert.IsNotNull(endp.Metadata, "Metadata not found");

                Assert.Throws <Saml20Exception>(() => assertion.CheckValid(AssertionUtil.GetTrustedSigners(assertion.Issuer)), "Assertion is no longer valid.");

                // Assert.IsNull(assertion.SigningKey, "Signing key is already present on assertion. Modify test.");
                // Assert.That(assertion.CheckSignature(Saml20SignonHandler.GetTrustedSigners(endp.Metadata.GetKeys(KeyTypes.Signing), endp)));
                // Assert.IsNotNull(assertion.SigningKey, "Signing key was not set on assertion instance.");
            }
            public void CanDecryptFOBSAssertion()
            {
                // Arrange
                var doc = AssertionUtil.LoadBase64EncodedXmlDocument(@"Assertions\fobs-assertion2");
                var encryptedList = doc.GetElementsByTagName(EncryptedAssertion.ElementName, Saml20Constants.Assertion);

                // Do some mock configuration.
                var config = new Saml2Configuration
                {
                    AllowedAudienceUris = new System.Collections.Generic.List<Uri>(),
                    IdentityProviders = new IdentityProviders()
                };
                config.AllowedAudienceUris.Add(new Uri("https://saml.safewhere.net"));
                config.IdentityProviders.AddByMetadataDirectory(@"Protocol\MetadataDocs\FOBS"); // Set it manually.

                var cert = new X509Certificate2(@"Certificates\SafewhereTest_SFS.pfx", "test1234");
                var encryptedAssertion = new Saml20EncryptedAssertion((RSA)cert.PrivateKey);

                encryptedAssertion.LoadXml((XmlElement)encryptedList[0]);

                // Act
                encryptedAssertion.Decrypt();

                // Retrieve metadata
                var assertion = new Saml20Assertion(encryptedAssertion.Assertion.DocumentElement, null, false, TestConfiguration.Configuration);
                var endp = config.IdentityProviders.FirstOrDefault(x => x.Id == assertion.Issuer);

                // Assert
                Assert.That(encryptedList.Count == 1);
                Assert.IsNotNull(endp, "Endpoint not found");
                Assert.IsNotNull(endp.Metadata, "Metadata not found");

                try {
                    assertion.CheckValid(AssertionUtil.GetTrustedSigners(assertion.Issuer));
                    Assert.Fail("Verification should fail. Token does not include its signing key.");
                }
                catch (InvalidOperationException) {
                }

                Assert.IsNull(assertion.SigningKey, "Signing key is already present on assertion. Modify test.");
                //Assert.IsTrue("We have tested this next test" == "");
                //Assert.That(assertion.CheckSignature(Saml20SignonHandler.GetTrustedSigners(endp.Metadata.GetKeys(KeyTypes.Signing), endp)));
                //Assert.IsNotNull(assertion.SigningKey, "Signing key was not set on assertion instance.");
            }
 private static Saml20EncryptedAssertion GetDecryptedAssertion(XmlElement elem)
 {
     Saml20EncryptedAssertion decryptedAssertion = new Saml20EncryptedAssertion((RSA)FederationConfig.GetConfig().SigningCertificate.GetCertificate().PrivateKey);
     decryptedAssertion.LoadXml(elem);
     decryptedAssertion.Decrypt();
     return decryptedAssertion;
 }
        /// <summary>
        /// Gets the decrypted assertion.
        /// </summary>
        /// <param name="elem">The elem.</param>
        /// <returns>The decrypted <see cref="Saml20EncryptedAssertion"/>.</returns>
        private static Saml20EncryptedAssertion GetDecryptedAssertion(XmlElement elem)
        {
            Logger.Debug(TraceMessages.EncryptedAssertionDecrypting);

            var decryptedAssertion = new Saml20EncryptedAssertion((RSA)Saml2Config.GetConfig().ServiceProvider.SigningCertificate.GetCertificate().PrivateKey);
            decryptedAssertion.LoadXml(elem);
            decryptedAssertion.Decrypt();

            Logger.DebugFormat(TraceMessages.EncryptedAssertionDecrypted, decryptedAssertion.Assertion.DocumentElement.OuterXml);

            return decryptedAssertion;
        }