From 36be48aa5076665fd3bfa179fc32884ff2a82367 Mon Sep 17 00:00:00 2001 From: Michael Reidun Engelbrecht Larsen Date: Thu, 18 Feb 2021 16:15:21 +0100 Subject: [PATCH] Updated log4net and NUnit --- .../dk.nita.saml20.ext.audit.log4net.csproj | 8 +- .../packages.config | 2 +- .../Saml20/ArtifactTest.cs | 21 +- .../Saml20/DKSAML20ProfileValidationTest.cs | 68 +-- .../Saml20/EncryptedAssertionTest.cs | 57 +-- .../Saml20/Protocol/XmlSignatureUtilsTest.cs | 16 +- .../Saml20/Saml20CoreValidationTest.cs | 389 +++++++++++------- .../Saml20/SignatureTest.cs | 29 +- .../dk.nita.test.saml20.csproj | 13 +- .../dk.nita.test.saml20/packages.config | 2 +- 10 files changed, 349 insertions(+), 256 deletions(-) diff --git a/src/dk.nita.saml20/dk.nita.saml20.ext.audit.log4net/dk.nita.saml20.ext.audit.log4net.csproj b/src/dk.nita.saml20/dk.nita.saml20.ext.audit.log4net/dk.nita.saml20.ext.audit.log4net.csproj index eb85303..29345ee 100644 --- a/src/dk.nita.saml20/dk.nita.saml20.ext.audit.log4net/dk.nita.saml20.ext.audit.log4net.csproj +++ b/src/dk.nita.saml20/dk.nita.saml20.ext.audit.log4net/dk.nita.saml20.ext.audit.log4net.csproj @@ -36,11 +36,13 @@ bin\Release\dk.nita.saml20.ext.audit.log4net.xml - - ..\packages\log4net.2.0.1\lib\net40-full\log4net.dll + + ..\packages\log4net.2.0.12\lib\net45\log4net.dll + + @@ -55,7 +57,6 @@ - @@ -64,6 +65,7 @@ + diff --git a/src/dk.nita.saml20/dk.nita.saml20.ext.audit.log4net/packages.config b/src/dk.nita.saml20/dk.nita.saml20.ext.audit.log4net/packages.config index 0752455..43bfb75 100644 --- a/src/dk.nita.saml20/dk.nita.saml20.ext.audit.log4net/packages.config +++ b/src/dk.nita.saml20/dk.nita.saml20.ext.audit.log4net/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/ArtifactTest.cs b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/ArtifactTest.cs index 8b0a963..0df195e 100644 --- a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/ArtifactTest.cs +++ b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/ArtifactTest.cs @@ -38,9 +38,9 @@ public void ArtifactCreateParse() Assert.That(typeCode == parsedTypeCode, "Original and parsed typeCode did not match"); Assert.That(endpointIndex == parsedEndpointIndex, "Original and parsed endpointIndex did not match"); - for(int i = 0; i < 20; i++) + for (int i = 0; i < 20; i++) { - if(sourceIdHash[i] != parsedSourceIdHash[i]) + if (sourceIdHash[i] != parsedSourceIdHash[i]) Assert.Fail("Original and parsed sourceIdHash are not identical"); } @@ -52,7 +52,6 @@ public void ArtifactCreateParse() } [Test] - [ExpectedException(typeof(ArgumentException))] public void CreateError1() { Int16 typeCode = 4; @@ -60,11 +59,12 @@ public void CreateError1() byte[] sourceIdHash = new byte[19]; byte[] messageHandle = new byte[20]; - ArtifactUtil.CreateArtifact(typeCode, endpointIndex, sourceIdHash, messageHandle); + + + Assert.Throws(() => ArtifactUtil.CreateArtifact(typeCode, endpointIndex, sourceIdHash, messageHandle)); } [Test] - [ExpectedException(typeof(ArgumentException))] public void CreateError2() { Int16 typeCode = 4; @@ -72,11 +72,10 @@ public void CreateError2() byte[] sourceIdHash = new byte[20]; byte[] messageHandle = new byte[19]; - ArtifactUtil.CreateArtifact(typeCode, endpointIndex, sourceIdHash, messageHandle); + Assert.Throws(() => ArtifactUtil.CreateArtifact(typeCode, endpointIndex, sourceIdHash, messageHandle)); } [Test] - [ExpectedException(typeof(ArgumentException))] public void ParseError1() { Int16 parsedTypeCode = -1; @@ -85,12 +84,11 @@ public void ParseError1() byte[] parsedMessageHandle = new byte[20]; string artifact = string.Empty; - ArtifactUtil.ParseArtifact(artifact, ref parsedTypeCode, ref parsedEndpointIndex, ref parsedSourceIdHash, ref parsedMessageHandle); + Assert.Throws(() => ArtifactUtil.ParseArtifact(artifact, ref parsedTypeCode, ref parsedEndpointIndex, ref parsedSourceIdHash, ref parsedMessageHandle)); } [Test] - [ExpectedException(typeof(ArgumentException))] public void ParseError2() { Int16 parsedTypeCode = -1; @@ -98,11 +96,10 @@ public void ParseError2() byte[] parsedSourceIdHash = new byte[20]; byte[] parsedMessageHandle = new byte[19]; string artifact = string.Empty; - ArtifactUtil.ParseArtifact(artifact, ref parsedTypeCode, ref parsedEndpointIndex, ref parsedSourceIdHash, ref parsedMessageHandle); + Assert.Throws(() => ArtifactUtil.ParseArtifact(artifact, ref parsedTypeCode, ref parsedEndpointIndex, ref parsedSourceIdHash, ref parsedMessageHandle)); } [Test] - [ExpectedException(typeof(ArgumentException))] public void ParseError3() { Int16 parsedTypeCode = -1; @@ -110,7 +107,7 @@ public void ParseError3() byte[] parsedSourceIdHash = new byte[20]; byte[] parsedMessageHandle = new byte[20]; string artifact = string.Empty; - ArtifactUtil.ParseArtifact(artifact, ref parsedTypeCode, ref parsedEndpointIndex, ref parsedSourceIdHash, ref parsedMessageHandle); + Assert.Throws(() => ArtifactUtil.ParseArtifact(artifact, ref parsedTypeCode, ref parsedEndpointIndex, ref parsedSourceIdHash, ref parsedMessageHandle)); } diff --git a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/DKSAML20ProfileValidationTest.cs b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/DKSAML20ProfileValidationTest.cs index bbe84e8..cd5b549 100644 --- a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/DKSAML20ProfileValidationTest.cs +++ b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/DKSAML20ProfileValidationTest.cs @@ -8,7 +8,7 @@ using NUnit.Framework; using dk.nita.saml20; using dk.nita.saml20.Validation; -using Assertion=dk.nita.saml20.Schema.Core.Assertion; +using Assertion = dk.nita.saml20.Schema.Core.Assertion; namespace dk.nita.test.Saml20 { @@ -22,7 +22,7 @@ public class DKSAML20ProfileValidationTest public DKSAML20ProfileValidationTest() { - _validator = new DKSaml20AssertionValidator(AssertionUtil.GetAudiences(),false); + _validator = new DKSaml20AssertionValidator(AssertionUtil.GetAudiences(), false); } #region Tests @@ -41,7 +41,6 @@ public void TestRetrieveIssuer() /// Test that EncryptedData element with the correct Type value is disallowed by the DK Saml 2.0 validation /// [Test] - [ExpectedException(typeof(DKSaml20FormatException), ExpectedMessage = "The DK-SAML 2.0 profile does not allow encrypted attributes.")] public void AttributeStatement_Invalid_EncryptedAttribute_DKSaml20() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -57,21 +56,23 @@ public void AttributeStatement_Invalid_EncryptedAttribute_DKSaml20() XmlDocument doc = AssertionUtil.ConvertAssertion(saml20Assertion); var assertion = new Saml20Assertion(doc.DocumentElement, null, false); - assertion.Validate(DateTime.MinValue); + + Assert.Throws( + () => assertion.Validate(DateTime.MinValue), + "The DK-SAML 2.0 profile does not allow encrypted attributes."); } /// /// Add an <AuthzDecisionStatement> to the list of statements and check that this is detected as a violation. /// [Test] - [ExpectedException(typeof(DKSaml20FormatException), ExpectedMessage = "The DK-SAML 2.0 profile requires exactly one \"AuthnStatement\" element and one \"AttributeStatement\" element.")] public void AttributeStatement_Invalid_Statementtype() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); AuthzDecisionStatement authzDecisionStatement = new AuthzDecisionStatement(); authzDecisionStatement.Decision = DecisionType.Permit; authzDecisionStatement.Resource = "http://safewhere.net"; - authzDecisionStatement.Action = new dk.nita.saml20.Schema.Core.Action[] { new dk.nita.saml20.Schema.Core.Action() }; + authzDecisionStatement.Action = new dk.nita.saml20.Schema.Core.Action[] { new dk.nita.saml20.Schema.Core.Action() }; authzDecisionStatement.Action[0].Namespace = "http://actionns.com"; authzDecisionStatement.Action[0].Value = "value"; @@ -81,7 +82,10 @@ public void AttributeStatement_Invalid_Statementtype() saml20Assertion.Items = statements.ToArray(); var assertion = new Saml20Assertion(AssertionUtil.ConvertAssertion(saml20Assertion).DocumentElement, null, false); - assertion.Validate(DateTime.MinValue); + + Assert.Throws( + () => assertion.Validate(DateTime.MinValue), + "The DK-SAML 2.0 profile requires exactly one \"AuthnStatement\" element and one \"AttributeStatement\" element."); } /// @@ -106,7 +110,7 @@ public void AttributeStatement_Invalid_Statementtype() // saml20Assertion.Issuer.Format = "http://example.com"; // TestAssertion(saml20Assertion, "The DK-SAML 2.0 Profile does not allow the \"Issuer\" element to have any attributes."); - + // saml20Assertion.Issuer.Format = null; // saml20Assertion.Issuer.NameQualifier = "NameQualifier"; @@ -116,7 +120,7 @@ public void AttributeStatement_Invalid_Statementtype() // saml20Assertion.Issuer.SPNameQualifier = "SPNameQualifier"; // TestAssertion(saml20Assertion, "The DK-SAML 2.0 Profile does not allow the \"Issuer\" element to have any attributes."); - + // saml20Assertion.Issuer.SPNameQualifier = null; // saml20Assertion.Issuer.SPProvidedID = "SPProvidedID"; @@ -156,8 +160,8 @@ public void Subject_Element() Assert.That(saml20Assertion.Subject.Items.Length > 0); - SubjectConfirmation subjectConfirmation = - (SubjectConfirmation) Array.Find(saml20Assertion.Subject.Items, delegate(object item) { return item is SubjectConfirmation; }); + SubjectConfirmation subjectConfirmation = + (SubjectConfirmation)Array.Find(saml20Assertion.Subject.Items, delegate (object item) { return item is SubjectConfirmation; }); Assert.IsNotNull(subjectConfirmation); string originalMethod = subjectConfirmation.Method; subjectConfirmation.Method = "IllegalMethod"; @@ -176,7 +180,7 @@ public void Subject_Element() TestAssertion(saml20Assertion, "The DK-SAML 2.0 Profile requires that the \"SubjectConfirmationData\" element contains the \"NotOnOrAfter\" attribute."); subjectConfirmation.SubjectConfirmationData.NotOnOrAfter = DateTime.UtcNow; - subjectConfirmation.SubjectConfirmationData.NotBefore = DateTime.UtcNow.Subtract(new TimeSpan(5,0,0,0)); + subjectConfirmation.SubjectConfirmationData.NotBefore = DateTime.UtcNow.Subtract(new TimeSpan(5, 0, 0, 0)); TestAssertion(saml20Assertion, "The DK-SAML 2.0 Profile disallows the use of the \"NotBefore\" attribute of the \"SubjectConfirmationData\" element."); subjectConfirmation.SubjectConfirmationData.NotBefore = null; @@ -201,11 +205,11 @@ public void Conditions_Element() List conditions = new List(saml20Assertion.Conditions.Items); - int index = conditions.FindIndex(delegate(ConditionAbstract cond) { return cond is AudienceRestriction; }); - Assert.That( index != -1); + int index = conditions.FindIndex(delegate (ConditionAbstract cond) { return cond is AudienceRestriction; }); + Assert.That(index != -1); conditions.RemoveAt(index); // Add another condition to avoid an empty list of conditions. - conditions.Add( new OneTimeUse()); + conditions.Add(new OneTimeUse()); saml20Assertion.Conditions.Items = conditions; TestAssertion(saml20Assertion, "The DK-SAML 2.0 profile requires that an \"AudienceRestriction\" element is present on the saml20Assertion."); @@ -214,12 +218,12 @@ public void Conditions_Element() /// /// Verify the rules for the <AuthnStatement> element, which are outlined in section 7.1.7 of [DKSAML] /// - [Test] + [Test] public void AuthnStatement_Element() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); AuthnStatement authnStmt = - (AuthnStatement)Array.Find(saml20Assertion.Items, delegate(StatementAbstract stmnt) { return stmnt is AuthnStatement; }); + (AuthnStatement)Array.Find(saml20Assertion.Items, delegate (StatementAbstract stmnt) { return stmnt is AuthnStatement; }); // Mess around with the AuthnStatement. { @@ -230,9 +234,9 @@ public void AuthnStatement_Element() } { - int index = - Array.FindIndex(authnStmt.AuthnContext.Items, - delegate(object o) { return o is string && o.ToString() == "urn:oasis:names:tc:SAML:2.0:ac:classes:X509"; }); + int index = + Array.FindIndex(authnStmt.AuthnContext.Items, + delegate (object o) { return o is string && o.ToString() == "urn:oasis:names:tc:SAML:2.0:ac:classes:X509"; }); object oldValue = authnStmt.AuthnContext.Items[index]; authnStmt.AuthnContext.Items[index] = "Hallelujagobble!!"; TestAssertion(saml20Assertion, "AuthnContextClassRef has a value which is not a wellformed absolute uri"); @@ -242,7 +246,7 @@ public void AuthnStatement_Element() // Remove it. saml20Assertion = AssertionUtil.GetBasicAssertion(); List statements = new List(saml20Assertion.Items); - statements.RemoveAll(delegate(StatementAbstract stmnt) { return stmnt is AuthnStatement; }); + statements.RemoveAll(delegate (StatementAbstract stmnt) { return stmnt is AuthnStatement; }); saml20Assertion.Items = statements.ToArray(); TestAssertion(saml20Assertion, "The DK-SAML 2.0 profile requires exactly one \"AuthnStatement\" element and one \"AttributeStatement\" element."); } @@ -250,15 +254,15 @@ public void AuthnStatement_Element() /// /// Verify the rules for the <AttributeStatement> element, which are outlined in section 7.1.8 of [DKSAML] /// - [Test] + [Test] public void AttributeStatement_Element() - { + { Predicate findAttributeStatement = - delegate(StatementAbstract stmnt) { return stmnt is AttributeStatement; }; + delegate (StatementAbstract stmnt) { return stmnt is AttributeStatement; }; Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); AttributeStatement attributeStatement = - (AttributeStatement) Array.Find(saml20Assertion.Items, findAttributeStatement); + (AttributeStatement)Array.Find(saml20Assertion.Items, findAttributeStatement); // Add an encrypted attribute. EncryptedElement encAtt = new EncryptedElement(); @@ -270,14 +274,14 @@ public void AttributeStatement_Element() TestAssertion(saml20Assertion, "The DK-SAML 2.0 profile does not allow encrypted attributes."); // Add an attribute with the wrong nameformat. -// Attribute att = DKSaml20EmailAttribute.create("test@example.com"); -// att.NameFormat = "http://example.com"; -// attributeStatement.Items = new object[] { att }; -// testAssertion(saml20Assertion, "The DK-SAML 2.0 profile requires that an attribute's \"NameFormat\" element is urn:oasis:names:tc:SAML:2.0:attrname-format:uri."); + // Attribute att = DKSaml20EmailAttribute.create("test@example.com"); + // att.NameFormat = "http://example.com"; + // attributeStatement.Items = new object[] { att }; + // testAssertion(saml20Assertion, "The DK-SAML 2.0 profile requires that an attribute's \"NameFormat\" element is urn:oasis:names:tc:SAML:2.0:attrname-format:uri."); // Clear all the attributes. attributeStatement.Items = new object[0]; - TestAssertion(saml20Assertion, "AttributeStatement MUST contain at least one Attribute or EncryptedAttribute"); + TestAssertion(saml20Assertion, "AttributeStatement MUST contain at least one Attribute or EncryptedAttribute"); // Remove it. saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -310,8 +314,8 @@ private void TestAssertion(Assertion saml20Assertion, string exceptionMsg) /// /// private static AttributeStatement GetAttributeStatement(List statements) - { - return (AttributeStatement) statements.Find(delegate(StatementAbstract ssa) { return ssa is AttributeStatement; }); + { + return (AttributeStatement)statements.Find(delegate (StatementAbstract ssa) { return ssa is AttributeStatement; }); } } } \ No newline at end of file diff --git a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/EncryptedAssertionTest.cs b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/EncryptedAssertionTest.cs index 9da337c..051b078 100644 --- a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/EncryptedAssertionTest.cs +++ b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/EncryptedAssertionTest.cs @@ -12,8 +12,8 @@ using dk.nita.saml20.config; using dk.nita.saml20; using dk.nita.saml20.protocol; -using Assertion=dk.nita.saml20.Schema.Core.Assertion; -using Saml20Assertion=dk.nita.saml20.Saml20Assertion; +using Assertion = dk.nita.saml20.Schema.Core.Assertion; +using Saml20Assertion = dk.nita.saml20.Saml20Assertion; namespace dk.nita.test.Saml20 { @@ -22,7 +22,7 @@ namespace dk.nita.test.Saml20 /// [TestFixture] public class EncryptedAssertionTest - { + { private static Saml20Assertion CreateDKSaml20TokenFromAssertion(Saml20EncryptedAssertion encAss) { return new Saml20Assertion(encAss.Assertion.DocumentElement, null, false); @@ -41,12 +41,12 @@ public void DecryptAssertion_01() /// An example on how to decrypt an encrypted assertion. /// private static void DecryptAssertion(string file) - { + { XmlDocument doc = new XmlDocument(); - doc.Load(file); - XmlElement encryptedDataElement = GetElement(dk.nita.saml20.Schema.XEnc.EncryptedData.ELEMENT_NAME, Saml20Constants.XENC, doc); + doc.Load(file); + XmlElement encryptedDataElement = GetElement(dk.nita.saml20.Schema.XEnc.EncryptedData.ELEMENT_NAME, Saml20Constants.XENC, doc); + - EncryptedData encryptedData = new EncryptedData(); encryptedData.LoadXml(encryptedDataElement); @@ -54,7 +54,7 @@ private static void DecryptAssertion(string file) Assert.That(nodelist.Count > 0); KeyInfo key = new KeyInfo(); - key.LoadXml((XmlElement) nodelist[0]); + key.LoadXml((XmlElement)nodelist[0]); // Review: Is it possible to figure out which certificate to load based on the Token? /* @@ -74,12 +74,12 @@ private static void DecryptAssertion(string file) { if (keyInfoClause is KeyInfoEncryptedKey) { - KeyInfoEncryptedKey keyInfoEncryptedKey = (KeyInfoEncryptedKey) keyInfoClause; + KeyInfoEncryptedKey keyInfoEncryptedKey = (KeyInfoEncryptedKey)keyInfoClause; EncryptedKey encryptedKey = keyInfoEncryptedKey.EncryptedKey; symmetricKey = new RijndaelManaged(); - + symmetricKey.Key = - EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, (RSA) cert.PrivateKey, false); + EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, (RSA)cert.PrivateKey, false); continue; } } @@ -141,11 +141,11 @@ public void GenerateEncryptedAssertion_01() encryptedAssertion.encryptedKey[0] = new saml20.Schema.XEnc.EncryptedKey(); XmlDocument result; - result = Serialization.Serialize(encryptedAssertion); + result = Serialization.Serialize(encryptedAssertion); XmlElement encryptedDataElement = GetElement(dk.nita.saml20.Schema.XEnc.EncryptedData.ELEMENT_NAME, Saml20Constants.XENC, result); EncryptedXml.ReplaceElement(encryptedDataElement, encryptedData, false); - } + } /// /// Attempts to decrypt the assertion in the file "EncryptedAssertion_01". @@ -160,7 +160,7 @@ public void TestAssertionDecryption_01() // Find the transport key. X509Certificate2 cert = new X509Certificate2(@"Saml20\Certificates\sts_dev_certificate.pfx", "test1234"); - Saml20EncryptedAssertion encryptedAssertion = new Saml20EncryptedAssertion((RSA) cert.PrivateKey, doc); + Saml20EncryptedAssertion encryptedAssertion = new Saml20EncryptedAssertion((RSA)cert.PrivateKey, doc); Assert.IsNull(encryptedAssertion.Assertion); // Check that it does not contain an assertion prior to decryption. encryptedAssertion.Decrypt(); Assert.IsNotNull(encryptedAssertion.Assertion); @@ -172,7 +172,7 @@ public void TestAssertionDecryption_01() /// Test that the Saml20EncryptedAssertion class is capable of finding keys that are "peer" included, /// ie. the <EncryptedKey> element is a sibling of the <EncryptedData> element. /// - [Test] + [Test] public void TestAssertionDecryption_02() { // Load the assertion @@ -186,13 +186,13 @@ public void TestAssertionDecryption_02() Assert.IsNull(encryptedAssertion.Assertion); // Check that it does not contain an assertion prior to decryption. encryptedAssertion.Decrypt(); Assert.IsNotNull(encryptedAssertion.Assertion); - } - + } + /// /// Test that the Saml20EncryptedAssertion class is capable of finding keys that are "peer" included, /// ie. the <EncryptedKey> element is a sibling of the <EncryptedData> element. /// - [Test] + [Test] public void TestAssertionDecryption_03() { // Load the assertion @@ -269,7 +269,7 @@ public void TestAssertionEncryption() encryptedAssertion.Assertion = AssertionUtil.GetTestAssertion_01(); X509Certificate2 cert = new X509Certificate2(@"Saml20\Certificates\sts_dev_certificate.pfx", "test1234"); - encryptedAssertion.TransportKey = (RSA) cert.PublicKey.Key; + encryptedAssertion.TransportKey = (RSA)cert.PublicKey.Key; encryptedAssertion.Encrypt(); @@ -289,12 +289,15 @@ public void TestAssertionEncryption() /// Tests that it is possible to specify the algorithm of the session key. /// [Test] - [ExpectedException(typeof(ArgumentException))] public void TestAlgorithmConfiguration_01() { - Saml20EncryptedAssertion encryptedAssertion = new Saml20EncryptedAssertion(); - encryptedAssertion.SessionKeyAlgorithm = "RSA"; - Assert.Fail("\"Saml20EncryptedAssertion\" class does not respond to incorrect algorithm identifying URI."); + Assert.Throws( + () => + { + Saml20EncryptedAssertion encryptedAssertion = new Saml20EncryptedAssertion(); + encryptedAssertion.SessionKeyAlgorithm = "RSA"; + Assert.Fail("\"Saml20EncryptedAssertion\" class does not respond to incorrect algorithm identifying URI."); + }); } /// @@ -319,11 +322,11 @@ public void TestAlgorithmConfiguration_02() Assert.IsNotNull(encryptedAssertionXML); // Verify that the EncryptionMethod element is set correctly. - XmlNodeList list = + XmlNodeList list = encryptedAssertionXML.GetElementsByTagName(dk.nita.saml20.Schema.XEnc.EncryptedData.ELEMENT_NAME, Saml20Constants.XENC); Assert.AreEqual(1, list.Count); - XmlElement el = (XmlElement) list[0]; + XmlElement el = (XmlElement)list[0]; // Go through the children and look for the EncryptionMethod element, and verify its algorithm attribute. bool encryptionMethodFound = false; @@ -332,7 +335,7 @@ public void TestAlgorithmConfiguration_02() if (node.LocalName == dk.nita.saml20.Schema.XEnc.EncryptionMethod.ELEMENT_NAME && node.NamespaceURI == Saml20Constants.XENC) { - el = (XmlElement) node; + el = (XmlElement)node; Assert.AreEqual(EncryptedXml.XmlEncAES128Url, el.GetAttribute("Algorithm")); encryptionMethodFound = true; } @@ -340,7 +343,7 @@ public void TestAlgorithmConfiguration_02() 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); + 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. diff --git a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/Protocol/XmlSignatureUtilsTest.cs b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/Protocol/XmlSignatureUtilsTest.cs index 6b58c7c..957124e 100644 --- a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/Protocol/XmlSignatureUtilsTest.cs +++ b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/Protocol/XmlSignatureUtilsTest.cs @@ -24,23 +24,23 @@ public void DetectSignature_01() } [Test] - [ExpectedException(typeof(InvalidOperationException))] public void DetectSignature_02() { XmlDocument doc = LoadDocument(@"Saml20\Assertions\EncryptedAssertion_01"); doc.PreserveWhitespace = false; - XmlSignatureUtils.IsSigned(doc); + Assert.Throws( + () => XmlSignatureUtils.IsSigned(doc)); } [Test] - [ExpectedException(typeof(InvalidOperationException))] public void CheckSignature_01() { - XmlDocument doc = LoadDocument(@"Saml20\Assertions\EncryptedAssertion_01"); - XmlSignatureUtils.CheckSignature(doc); + XmlDocument doc = LoadDocument(@"Saml20\Assertions\EncryptedAssertion_01"); + Assert.Throws( + () => XmlSignatureUtils.CheckSignature(doc)); } - [Test] + [Test] public void CheckSignature_02() { XmlDocument doc = LoadDocument(@"Saml20\Assertions\Saml2Assertion_01"); @@ -51,8 +51,8 @@ public void CheckSignature_02() public void ExtractKeyInfo_01() { XmlDocument doc = LoadDocument(@"Saml20\Assertions\Saml2Assertion_01"); - KeyInfo keyInfo = XmlSignatureUtils.ExtractSignatureKeys(doc); - Assert.IsNotNull(keyInfo); + KeyInfo keyInfo = XmlSignatureUtils.ExtractSignatureKeys(doc); + Assert.IsNotNull(keyInfo); } public static XmlDocument LoadDocument(string assertionFile) diff --git a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/Saml20CoreValidationTest.cs b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/Saml20CoreValidationTest.cs index 9e944ef..c94e7bb 100644 --- a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/Saml20CoreValidationTest.cs +++ b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/Saml20CoreValidationTest.cs @@ -11,7 +11,7 @@ using dk.nita.saml20.Utils; using dk.nita.saml20.Validation; using NUnit.Framework; -using Assertion=dk.nita.saml20.Schema.Core.Assertion; +using Assertion = dk.nita.saml20.Schema.Core.Assertion; namespace dk.nita.test.Saml20 { @@ -45,14 +45,16 @@ public void _0000_UTCFromStringTest() } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Email Format attribute MUST contain a Value that contains more than whitespace characters")] public void _0001_NameID_Invalid_EmptyEmail() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Email; nameID.Value = " "; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Email Format attribute MUST contain a Value that contains more than whitespace characters"); } /// @@ -69,22 +71,22 @@ public void _0001_NameID_Invalid_Email() string[] invalidEmails = new string[] { - "thisisnotavalid.email@ ", - "thisisnotavalidemail", - "thisisnotavalidemail.com", - "@thisisnotavalidemail.com", - " @thisisnotavalidemail.com", - "@ @thisisnotavalidemail.com", - " @ @thisisnotavalidemail.com", - " . @thisisnotavalidemail.com", - @"\. @thisisnotavalidemail.com", - @"\.\@thisisnotavalidemail.com", - @"a.\@thisisnotavalidemail.com", - @"<.>@thisisnotavalidemail.com", - @"<.a@thisisnotavalidemail.com", - "thisisnotavalid.email@", - "thisisnotavalid.email@ @", - "thisisnotavalid.email@ @ ", + "thisisnotavalid.email@ ", + "thisisnotavalidemail", + "thisisnotavalidemail.com", + "@thisisnotavalidemail.com", + " @thisisnotavalidemail.com", + "@ @thisisnotavalidemail.com", + " @ @thisisnotavalidemail.com", + " . @thisisnotavalidemail.com", + @"\. @thisisnotavalidemail.com", + @"\.\@thisisnotavalidemail.com", + @"a.\@thisisnotavalidemail.com", + @"<.>@thisisnotavalidemail.com", + @"<.a@thisisnotavalidemail.com", + "thisisnotavalid.email@", + "thisisnotavalid.email@ @", + "thisisnotavalid.email@ @ ", }; foreach (string email in invalidEmails) @@ -102,7 +104,7 @@ public void _0001_NameID_Invalid_Email() } } } - + [Test] public void _0001_NameID_Valid_Email() { @@ -114,36 +116,39 @@ public void _0001_NameID_Valid_Email() } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with X509SubjectName Format attribute MUST contain a Value that contains more than whitespace characters")] public void _0002_NameID_Invalid_EmptyX509SubjecName() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.X509SubjectName; nameID.Value = ""; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with X509SubjectName Format attribute MUST contain a Value that contains more than whitespace characters"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with X509SubjectName Format attribute MUST contain a Value that contains more than whitespace characters")] public void _0002_NameID_Invalid_X509SubjecName() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.X509SubjectName; nameID.Value = " "; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with X509SubjectName Format attribute MUST contain a Value that contains more than whitespace characters"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Windows Format attribute MUST contain a Value that contains more than whitespace characters")] public void _0002_NameID_Invalid_WindowsDomainQualifiedName_Whitespace() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Windows; nameID.Value = " "; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Windows Format attribute MUST contain a Value that contains more than whitespace characters"); } [Test] @@ -161,46 +166,50 @@ public void _0002_NameID_Valid_WindowsDomainQualifiedName() } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Kerberos Format attribute MUST contain a Value that contains more than whitespace characters")] public void _0002_NameID_Invalid_KerberosEmpty() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Kerberos; nameID.Value = ""; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Kerberos Format attribute MUST contain a Value that contains more than whitespace characters"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Kerberos Format attribute MUST contain a Value that contains more than whitespace characters")] public void _0002_NameID_Invalid_Kerberos() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Kerberos; nameID.Value = " "; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Kerberos Format attribute MUST contain a Value that contains more than whitespace characters"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Kerberos Format attribute MUST contain a Value with at least 3 characters")] public void _0002_NameID_Invalid_ContentKerberos1() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Kerberos; nameID.Value = @"b"; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Kerberos Format attribute MUST contain a Value with at least 3 characters"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Kerberos Format attribute MUST contain a Value that contains a '@'")] public void _0002_NameID_Invalid_ContentKerberos2() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Kerberos; nameID.Value = @"a\b"; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Kerberos Format attribute MUST contain a Value that contains a '@'"); } [Test] @@ -214,36 +223,39 @@ public void _0002_NameID_Valid_Kerberos() } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Entity Format attribute MUST contain a Value that contains more than whitespace characters")] public void _0002_NameID_Invalid_Entity_Empty() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Entity; nameID.Value = ""; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Entity Format attribute MUST contain a Value that contains more than whitespace characters"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Entity Format attribute MUST contain a Value that contains more than whitespace characters")] public void _0002_NameID_Invalid_Entity() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Entity; nameID.Value = " "; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Entity Format attribute MUST contain a Value that contains more than whitespace characters"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Entity Format attribute MUST have a Value that contains no more than 1024 characters")] public void _0002_NameID_Invalid_Entity_Length() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Entity; nameID.Value = new string('f', 1025); Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Entity Format attribute MUST have a Value that contains no more than 1024 characters"); } [Test] @@ -257,7 +269,6 @@ public void _0002_NameID_Valid_Entity() } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Entity Format attribute MUST NOT set the NameQualifier attribute")] public void _0002_NameID_Invalid_Entity_NameQualifier() { NameID nameID = new NameID(); @@ -265,11 +276,12 @@ public void _0002_NameID_Invalid_Entity_NameQualifier() nameID.Value = new string('f', 1024); nameID.NameQualifier = "ksljdf"; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Entity Format attribute MUST NOT set the NameQualifier attribute"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Entity Format attribute MUST NOT set the SPNameQualifier attribute")] public void _0002_NameID_Invalid_Entity_SPNameQualifier() { NameID nameID = new NameID(); @@ -277,11 +289,12 @@ public void _0002_NameID_Invalid_Entity_SPNameQualifier() nameID.Value = new string('f', 1024); nameID.SPNameQualifier = "ksljdf"; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Entity Format attribute MUST NOT set the SPNameQualifier attribute"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Entity Format attribute MUST NOT set the SPProvidedID attribute")] public void _0002_NameID_Invalid_Entity_SPProvidedID() { NameID nameID = new NameID(); @@ -289,40 +302,45 @@ public void _0002_NameID_Invalid_Entity_SPProvidedID() nameID.Value = new string('f', 1024); nameID.SPProvidedID = "ksljdf"; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Entity Format attribute MUST NOT set the SPProvidedID attribute"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Persistent Format attribute MUST contain a Value that contains more than whitespace characters")] public void _0002_NameID_Invalid_Persistent_Empty() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Persistent; nameID.Value = ""; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Persistent Format attribute MUST contain a Value that contains more than whitespace characters"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Persistent Format attribute MUST contain a Value that contains more than whitespace characters")] public void _0002_NameID_Invalid_Persistent() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Persistent; nameID.Value = " "; Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Persistent Format attribute MUST contain a Value that contains more than whitespace characters"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Persistent Format attribute MUST have a Value that contains no more than 256 characters")] public void _0002_NameID_Invalid_Persistent_Length() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Persistent; nameID.Value = new string('f', 257); Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Persistent Format attribute MUST have a Value that contains no more than 256 characters"); } [Test] @@ -336,25 +354,27 @@ public void _0002_NameID_Valid_Persistent() } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Transient Format attribute MUST have a Value with at least 16 characters (the equivalent of 128 bits)")] public void _0002_NameID_Invalid_Transient_MinLength() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Transient; nameID.Value = new string('f', 15); Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Transient Format attribute MUST have a Value with at least 16 characters (the equivalent of 128 bits)"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID with Transient Format attribute MUST have a Value that contains no more than 256 characters")] public void _0002_NameID_Invalid_Transient_MaxLength() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Transient; nameID.Value = new string('f', 257); Saml20NameIDValidator validator = new Saml20NameIDValidator(); - validator.ValidateNameID(nameID); + Assert.Throws( + () => validator.ValidateNameID(nameID), + "NameID with Transient Format attribute MUST have a Value that contains no more than 256 characters"); } [Test] @@ -383,7 +403,7 @@ public void _0100_BasicAssertionValid() Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); new XmlSerializer(typeof(Assertion)); - + CreateSaml20Token(saml20Assertion); } @@ -391,26 +411,29 @@ public void _0100_BasicAssertionValid() /// Tests validation of wrong version attribute /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Wrong value of version attribute on Assertion element")] public void WrongVersion() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); saml20Assertion.Version = "60"; - CreateSaml20Token(saml20Assertion); + + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "Wrong value of version attribute on Assertion element"); } /// /// Tests validation of missing ID attribute /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Assertion element must have the ID attribute set.")] public void MissingID() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); saml20Assertion.ID = null; - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "Assertion element must have the ID attribute set."); } // @@ -418,39 +441,42 @@ public void MissingID() /// Tests validation of Issuer Element presence /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Assertion element must have an issuer element.")] public void Issuer() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); saml20Assertion.Issuer = null; - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "Assertion element must have an issuer element."); } /// /// Tests validation of Issuer Element format /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NameID element has Format attribute which is not a wellformed absolute uri.")] public void IssuerFormat() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); saml20Assertion.Issuer.Format = "a non wellformed uri"; - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "NameID element has Format attribute which is not a wellformed absolute uri."); } /// /// Tests validation of required IssueInstant Element /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Assertion element must have the IssueInstant attribute set.")] public void IssueInstant() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); saml20Assertion.IssueInstant = null; - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "Assertion element must have the IssueInstant attribute set."); } #endregion @@ -461,7 +487,6 @@ public void IssueInstant() /// Tests the validation that ensures at most 1 OneTimeUse condition /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Assertion contained more than one condition of type OneTimeUse")] public void OneTimeUse() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -474,14 +499,13 @@ public void OneTimeUse() saml20Assertion.Conditions.Items = conditions; - CreateSaml20Token(saml20Assertion); + Assert.Throws(() => CreateSaml20Token(saml20Assertion), "Assertion contained more than one condition of type OneTimeUse"); } /// /// Tests the validation that ensures at most 1 ProxyRestriction condition /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Assertion contained more than one condition of type ProxyRestriction")] public void ProxyRestriction() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -494,14 +518,13 @@ public void ProxyRestriction() saml20Assertion.Conditions.Items = conditions; - CreateSaml20Token(saml20Assertion); + Assert.Throws(() => CreateSaml20Token(saml20Assertion), "Assertion contained more than one condition of type ProxyRestriction"); } /// /// Tests the validation that ensures the Count property tp be a non-negative integer /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Count attribute of ProxyRestriction MUST BE a non-negative integer")] public void ProxyRestriction_Invalid_Count() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -514,7 +537,7 @@ public void ProxyRestriction_Invalid_Count() conditions.AddRange(saml20Assertion.Conditions.Items); saml20Assertion.Conditions.Items = conditions; - CreateSaml20Token(saml20Assertion); + Assert.Throws(() => CreateSaml20Token(saml20Assertion), "Count attribute of ProxyRestriction MUST BE a non-negative integer"); } /// @@ -540,20 +563,19 @@ public void ProxyRestriction_Valid_Count() /// Tests the validation that ensures the Count property tp be a non-negative integer /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "ProxyRestriction Audience MUST BE a wellformed uri")] public void ProxyRestriction_Invalid_Audience() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); List conditions = new List(); ProxyRestriction proxyRestriction = new ProxyRestriction(); - proxyRestriction.Audience = new string[] {"urn:a.wellformed:uri", "http://another/wellformed/uri", "a malformed uri"}; + proxyRestriction.Audience = new string[] { "urn:a.wellformed:uri", "http://another/wellformed/uri", "a malformed uri" }; conditions.Add(proxyRestriction); conditions.AddRange(saml20Assertion.Conditions.Items); saml20Assertion.Conditions.Items = conditions; - CreateSaml20Token(saml20Assertion); + Assert.Throws(() => CreateSaml20Token(saml20Assertion), "ProxyRestriction Audience MUST BE a wellformed uri"); } /// @@ -566,7 +588,7 @@ public void ProxyRestriction_Valid_Audience() List conditions = new List(); ProxyRestriction proxyRestriction = new ProxyRestriction(); - proxyRestriction.Audience = new string[] { "urn:a.wellformed:uri", "http://another/wellformed/uri"}; + proxyRestriction.Audience = new string[] { "urn:a.wellformed:uri", "http://another/wellformed/uri" }; conditions.Add(proxyRestriction); conditions.AddRange(saml20Assertion.Conditions.Items); @@ -618,7 +640,6 @@ public void TimeRestriction_NotBefore_Valid_Now() /// Test validity of assertion when condition has an invalid NotBefore time restriction /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Conditions.NotBefore is not within expected range")] public void TimeRestriction_NotBefore_Invalid() { // Test with NotBefore that post-dates now @@ -627,7 +648,9 @@ public void TimeRestriction_NotBefore_Invalid() saml20Assertion.Conditions.NotOnOrAfter = null; Saml20AssertionValidator validator = new Saml20AssertionValidator(AssertionUtil.GetAudiences(), false); - validator.ValidateTimeRestrictions(saml20Assertion, new TimeSpan(), DateTime.UtcNow); + Assert.Throws( + () => validator.ValidateTimeRestrictions(saml20Assertion, new TimeSpan(), DateTime.UtcNow), + "Conditions.NotBefore is not within expected range"); } /// @@ -647,7 +670,6 @@ public void TimeRestriction_NotOnOrAfter_Valid_Tomorrow() /// Test validity of assertion when condition has an invalid NotOnOrAfter time restriction /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Conditions.NotOnOrAfter is not within expected range")] public void TimeRestriction_NotOnOrAfter_Invalid_Yesterday() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -656,14 +678,15 @@ public void TimeRestriction_NotOnOrAfter_Invalid_Yesterday() saml20Assertion.Conditions.NotOnOrAfter = DateTime.UtcNow.AddDays(-1); Saml20AssertionValidator validator = new Saml20AssertionValidator(AssertionUtil.GetAudiences(), false); - validator.ValidateTimeRestrictions(saml20Assertion, new TimeSpan(), DateTime.UtcNow); + Assert.Throws( + () => validator.ValidateTimeRestrictions(saml20Assertion, new TimeSpan(), DateTime.UtcNow), + "Conditions.NotOnOrAfter is not within expected range"); } /// /// Test validity of assertion when condition has an invalid NotOnOrAfter time restriction /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Conditions.NotOnOrAfter is not within expected range")] public void TimeRestriction_NotOnOrAfter_Invalid_Now() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -672,7 +695,10 @@ public void TimeRestriction_NotOnOrAfter_Invalid_Now() saml20Assertion.Conditions.NotOnOrAfter = DateTime.UtcNow; Saml20AssertionValidator validator = new Saml20AssertionValidator(AssertionUtil.GetAudiences(), false); - validator.ValidateTimeRestrictions(saml20Assertion, new TimeSpan(), DateTime.UtcNow); + + Assert.Throws( + () => validator.ValidateTimeRestrictions(saml20Assertion, new TimeSpan(), DateTime.UtcNow), + "Conditions.NotOnOrAfter is not within expected range"); } /// @@ -692,7 +718,6 @@ public void TimeRestriction_Both() /// consider audience-restricted assertions valid /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "The service is not configured to meet any audience restrictions")] public void AudienceRestriction_Invalid_NoConfiguration() { FederationConfig sp = FederationConfig.GetConfig(); @@ -702,7 +727,10 @@ public void AudienceRestriction_Invalid_NoConfiguration() sp.AllowedAudienceUris.Audiences = null; Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); - CreateSaml20Token(saml20Assertion); + + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "The service is not configured to meet any audience restrictions"); } finally { @@ -715,7 +743,6 @@ public void AudienceRestriction_Invalid_NoConfiguration() /// consider audience-restricted assertions valid /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "The service is not configured to meet the given audience restrictions")] public void AudienceRestriction_Invalid_ConfigurationSetup() { FederationConfig sp = FederationConfig.GetConfig(); @@ -725,7 +752,9 @@ public void AudienceRestriction_Invalid_ConfigurationSetup() sp.AllowedAudienceUris.Audiences = new List(new string[] { "urn:lalal" }); Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "The service is not configured to meet the given audience restrictions"); } finally { @@ -737,22 +766,22 @@ public void AudienceRestriction_Invalid_ConfigurationSetup() /// Test that audience-restricted assertions are not valid if the restriction values are incorrectly formatted /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Audience element has value which is not a wellformed absolute uri")] public void AudienceRestriction_Invalid_Assertion() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); AudienceRestriction sar = new AudienceRestriction(); - sar.Audience = new List( new string[] { "malformed uri" }); + sar.Audience = new List(new string[] { "malformed uri" }); saml20Assertion.Conditions.Items = new List(new ConditionAbstract[] { sar }); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "Audience element has value which is not a wellformed absolute uri"); } /// /// Test that audience-restricted assertions are not valid if ANY of the audience restrictions is not met /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "The service is not configured to meet the given audience restrictions")] public void AudienceRestriction_Invalid_MultipleAudienceRestrictions() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -764,7 +793,9 @@ public void AudienceRestriction_Invalid_MultipleAudienceRestrictions() saml20Assertion.Conditions.Items = audienceConditions; - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "The service is not configured to meet the given audience restrictions"); } /// @@ -816,7 +847,6 @@ public void AudienceRestriction_Valid_SeveralAudiences() /// Tests the validation that ensures that a subject MUST have at least one subelement /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Subject MUST contain either an identifier or a subject confirmation")] public void SubjectConfirmation() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -824,75 +854,85 @@ public void SubjectConfirmation() saml20Assertion.Subject.Items = new object[] { }; Saml20SubjectValidator validator = new Saml20SubjectValidator(); - validator.ValidateSubject(saml20Assertion.Subject); + + Assert.Throws( + () => validator.ValidateSubject(saml20Assertion.Subject), + "Subject MUST contain either an identifier or a subject confirmation"); } /// /// Tests the validation that ensures that a subject MUST have at least one subelement of correct type /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Subject must have either NameID, EncryptedID or SubjectConfirmation subelement.")] public void SubjectConfirmation_WrongIdentifier() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); saml20Assertion.Subject.Items = new object[] { String.Empty, 24, new List(1), new Advice() }; Saml20SubjectValidator validator = new Saml20SubjectValidator(); - validator.ValidateSubject(saml20Assertion.Subject); + Assert.Throws( + () => validator.ValidateSubject(saml20Assertion.Subject), + "Subject must have either NameID, EncryptedID or SubjectConfirmation subelement."); } /// /// Tests the validation of the SubjectConfirmation element's method attribute. /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Method attribute of SubjectConfirmation MUST contain at least one non-whitespace character")] public void SubjectConfirmationEmptyMethod() { SubjectConfirmation sct = new SubjectConfirmation(); sct.Method = " "; Saml20SubjectConfirmationValidator validator = new Saml20SubjectConfirmationValidator(); - validator.ValidateSubjectConfirmation(sct); + + Assert.Throws( + () => validator.ValidateSubjectConfirmation(sct), + "Method attribute of SubjectConfirmation MUST contain at least one non-whitespace character"); } /// /// Tests the validation of the SubjectConfirmation element's method attribute. /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "SubjectConfirmation element has Method attribute which is not a wellformed absolute uri.")] public void SubjectConfirmationWrongMethod() { SubjectConfirmation sct = new SubjectConfirmation(); sct.Method = "malformed uri"; Saml20SubjectConfirmationValidator validator = new Saml20SubjectConfirmationValidator(); - validator.ValidateSubjectConfirmation(sct); + Assert.Throws( + () => validator.ValidateSubjectConfirmation(sct), + "SubjectConfirmation element has Method attribute which is not a wellformed absolute uri."); } /// /// Tests the validation of the SubjectConfirmationData recipient element /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Recipient of SubjectConfirmationData must be a wellformed absolute URI.")] public void SubjectConfirmationDataEmptyRecipient() { SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData(); subjectConfirmationData.Recipient = " "; Saml20SubjectConfirmationDataValidator validator = new Saml20SubjectConfirmationDataValidator(); - validator.ValidateSubjectConfirmationData(subjectConfirmationData); + Assert.Throws( + () => validator.ValidateSubjectConfirmationData(subjectConfirmationData), + "Recipient of SubjectConfirmationData must be a wellformed absolute URI."); } /// /// Tests the validation of the SubjectConfirmationData recipient element /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Recipient of SubjectConfirmationData must be a wellformed absolute URI.")] public void SubjectConfirmationDataInvalidRecipient() { SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData(); subjectConfirmationData.Recipient = "malformed uri"; Saml20SubjectConfirmationDataValidator validator = new Saml20SubjectConfirmationDataValidator(); - validator.ValidateSubjectConfirmationData(subjectConfirmationData); + + Assert.Throws( + () => validator.ValidateSubjectConfirmationData(subjectConfirmationData), + "Recipient of SubjectConfirmationData must be a wellformed absolute URI."); } /// @@ -914,7 +954,6 @@ public void SubjectConfirmationDataValidRecipient() /// Tests the validation of the SubjectConfirmationData {NotBefore, NotOnOrAfter} attributes /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "NotBefore 2008-01-30T17:13:00.5Z MUST BE less than NotOnOrAfter 2008-01-30T16:13:00.5Z on SubjectConfirmationData")] public void SubjectConfirmationDataInvalidTimeInterval() { SubjectConfirmationData subjectConfirmationData = new SubjectConfirmationData(); @@ -922,7 +961,9 @@ public void SubjectConfirmationDataInvalidTimeInterval() subjectConfirmationData.NotOnOrAfter = subjectConfirmationData.NotBefore.Value.AddHours(-1); Saml20SubjectConfirmationDataValidator validator = new Saml20SubjectConfirmationDataValidator(); - validator.ValidateSubjectConfirmationData(subjectConfirmationData); + Assert.Throws( + () => validator.ValidateSubjectConfirmationData(subjectConfirmationData), + "NotBefore 2008-01-30T17:13:00.5Z MUST BE less than NotOnOrAfter 2008-01-30T16:13:00.5Z on SubjectConfirmationData"); } /// /// Tests the validation of the SubjectConfirmationData {NotBefore, NotOnOrAfter} attributes @@ -952,18 +993,18 @@ public void SubjectConfirmationDataValidTimeIntervalSettings() } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "SubjectConfirmationData element MUST have at least one " + KeyInfo.ELEMENT_NAME + " subelement")] public void SubjectConfirmationData_Invalid_KeyInfoConfirmationData_NoAnyElement() { KeyInfoConfirmationData subjectConfirmationData = new KeyInfoConfirmationData(); subjectConfirmationData.Recipient = "urn:wellformed.uri:ok"; Saml20SubjectConfirmationDataValidator validator = new Saml20SubjectConfirmationDataValidator(); - validator.ValidateSubjectConfirmationData(subjectConfirmationData); + Assert.Throws( + () => validator.ValidateSubjectConfirmationData(subjectConfirmationData), + "SubjectConfirmationData element MUST have at least one " + KeyInfo.ELEMENT_NAME + " subelement"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "SubjectConfirmationData element MUST contain at least one " + KeyInfo.ELEMENT_NAME + " in namespace " + Saml20Constants.XMLDSIG)] public void SubjectConfirmationData_Invalid_KeyInfoConfirmationData_IncompleteAnyElement() { KeyInfoConfirmationData subjectConfirmationData = new KeyInfoConfirmationData(); @@ -972,12 +1013,13 @@ public void SubjectConfirmationData_Invalid_KeyInfoConfirmationData_IncompleteAn subjectConfirmationData.AnyElements = new XmlElement[] { doc.CreateElement("ds", "KeyInfo", "http://wrongNameSpace.uri") }; Saml20SubjectConfirmationDataValidator validator = new Saml20SubjectConfirmationDataValidator(); - validator.ValidateSubjectConfirmationData(subjectConfirmationData); + Assert.Throws( + () => validator.ValidateSubjectConfirmationData(subjectConfirmationData), + "SubjectConfirmationData element MUST contain at least one " + KeyInfo.ELEMENT_NAME + " in namespace " + Saml20Constants.XMLDSIG); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "KeyInfo subelement of SubjectConfirmationData MUST NOT be empty")] public void SubjectConfirmationData_Invalid_KeyInfoConfirmationData_IncompleteAnyElement_NoChildren() { KeyInfoConfirmationData subjectConfirmationData = new KeyInfoConfirmationData(); @@ -986,11 +1028,12 @@ public void SubjectConfirmationData_Invalid_KeyInfoConfirmationData_IncompleteAn subjectConfirmationData.AnyElements = new XmlElement[] { doc.CreateElement("ds", "KeyInfo", Saml20Constants.XMLDSIG) }; Saml20SubjectConfirmationDataValidator validator = new Saml20SubjectConfirmationDataValidator(); - validator.ValidateSubjectConfirmationData(subjectConfirmationData); + Assert.Throws( + () => validator.ValidateSubjectConfirmationData(subjectConfirmationData), + "KeyInfo subelement of SubjectConfirmationData MUST NOT be empty"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "SubjectConfirmationData element MUST contain at least one " + KeyInfo.ELEMENT_NAME + " in namespace " + Saml20Constants.XMLDSIG)] public void SubjectConfirmationData_Invalid_KeyInfoConfirmationData_WrongAnyElement() { KeyInfoConfirmationData subjectConfirmationData = new KeyInfoConfirmationData(); @@ -1002,7 +1045,9 @@ public void SubjectConfirmationData_Invalid_KeyInfoConfirmationData_WrongAnyElem subjectConfirmationData.AnyElements = new XmlElement[] { elem }; Saml20SubjectConfirmationDataValidator validator = new Saml20SubjectConfirmationDataValidator(); - validator.ValidateSubjectConfirmationData(subjectConfirmationData); + Assert.Throws( + () => validator.ValidateSubjectConfirmationData(subjectConfirmationData), + "SubjectConfirmationData element MUST contain at least one " + KeyInfo.ELEMENT_NAME + " in namespace " + Saml20Constants.XMLDSIG); } [Test] @@ -1021,7 +1066,6 @@ public void SubjectConfirmationData_Valid_KeyInfoConfirmationData() } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "SubjectConfirmationData element MUST have at least one " + KeyInfo.ELEMENT_NAME + " subelement")] public void SubjectConfirmationData_Method_HolderOfKey_Invalid_NoKeyInfo() { SubjectConfirmation subjectConfirmation = new SubjectConfirmation(); @@ -1029,7 +1073,10 @@ public void SubjectConfirmationData_Method_HolderOfKey_Invalid_NoKeyInfo() subjectConfirmation.SubjectConfirmationData = new SubjectConfirmationData(); Saml20SubjectConfirmationValidator validator = new Saml20SubjectConfirmationValidator(); - validator.ValidateSubjectConfirmation(subjectConfirmation); + + Assert.Throws( + () => validator.ValidateSubjectConfirmation(subjectConfirmation), + "SubjectConfirmationData element MUST have at least one " + KeyInfo.ELEMENT_NAME + " subelement"); } [Test] @@ -1055,7 +1102,6 @@ public void SubjectConfirmationData_Method_HolderOfKey_Valid() /// Tests that AuthnStatement objects must have an AuthnInstant attribute /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthnStatement MUST have an AuthnInstant attribute")] public void AuthnStatement_Invalid_AuthnInstant() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1064,14 +1110,16 @@ public void AuthnStatement_Invalid_AuthnInstant() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AuthnStatement MUST have an AuthnInstant attribute"); } /// /// Tests that AuthnStatement objects must have an AuthnInstant attribute /// - [Ignore] // TODO: test data needs fixing - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthnStatement attribute SessionNotOnOrAfter MUST be in the future")] + [Ignore("test data needs fixing")] // TODO: test data needs fixing public void AuthnStatement_Invalid_SessionNotOnOrAfter() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1084,14 +1132,16 @@ public void AuthnStatement_Invalid_SessionNotOnOrAfter() saml20Assertion.Items = statements.ToArray(); Saml20AssertionValidator validator = new Saml20AssertionValidator(AssertionUtil.GetAudiences(), false); - validator.ValidateTimeRestrictions(saml20Assertion, new TimeSpan(0, 0, 0), DateTime.UtcNow); + + Assert.Throws( + () => validator.ValidateTimeRestrictions(saml20Assertion, new TimeSpan(0, 0, 0), DateTime.UtcNow), + "AuthnStatement attribute SessionNotOnOrAfter MUST be in the future"); } /// /// Tests that AuthnStatement objects must have an AuthnContext element /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthnStatement MUST have an AuthnContext element")] public void AuthnStatement_Invalid_AuthnContextNull() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1103,14 +1153,16 @@ public void AuthnStatement_Invalid_AuthnContextNull() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AuthnStatement MUST have an AuthnContext element"); } /// /// Tests that AuthnStatement objects must have non-null contents /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthnContext element MUST contain at least one AuthnContextClassRef, AuthnContextDecl or AuthnContextDeclRef element")] public void AuthnStatement_Invalid_AuthnContextNoContextItems() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1123,14 +1175,15 @@ public void AuthnStatement_Invalid_AuthnContextNoContextItems() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AuthnContext element MUST contain at least one AuthnContextClassRef, AuthnContextDecl or AuthnContextDeclRef element"); } /// /// Tests that AuthnStatement objects must have non-empty contents /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthnContext element MUST contain at least one AuthnContextClassRef, AuthnContextDecl or AuthnContextDeclRef element")] public void AuthnStatement_Invalid_AuthnContextEmpty() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1145,14 +1198,15 @@ public void AuthnStatement_Invalid_AuthnContextEmpty() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AuthnContext element MUST contain at least one AuthnContextClassRef, AuthnContextDecl or AuthnContextDeclRef element"); } /// /// Tests that AuthnStatement objects must have a AuthnContextClassRef type as the first element if it is present /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthnContextClassRef must be in the first element")] public void AuthnStatement_Invalid_AuthnContextClassRef_MustBeFirst() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1167,14 +1221,15 @@ public void AuthnStatement_Invalid_AuthnContextClassRef_MustBeFirst() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AuthnContextClassRef must be in the first element"); } /// /// Tests that AuthnStatement objects must have no more than 2 {AuthnContextClassRef, AuthnContextDeclRef} elements /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthnContext MUST NOT contain more than two elements.")] public void AuthnStatement_Invalid_AuthnContext_Max2Refs() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1189,7 +1244,9 @@ public void AuthnStatement_Invalid_AuthnContext_Max2Refs() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AuthnContext MUST NOT contain more than two elements."); } @@ -1197,7 +1254,6 @@ public void AuthnStatement_Invalid_AuthnContext_Max2Refs() /// Tests that AuthnStatement objects must have an valid uri content for AuthnContextClassRef types /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthnContextClassRef has a value which is not a wellformed absolute uri")] public void AuthnStatement_Invalid_AuthnContextClassRefUri() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1206,20 +1262,21 @@ public void AuthnStatement_Invalid_AuthnContextClassRefUri() sas.AuthnInstant = DateTime.UtcNow; sas.SessionNotOnOrAfter = DateTime.UtcNow.AddHours(1); sas.AuthnContext = new AuthnContext(); - sas.AuthnContext.Items = new object[2] { String.Empty, "urn:a.valid.uri:string"}; + sas.AuthnContext.Items = new object[2] { String.Empty, "urn:a.valid.uri:string" }; sas.AuthnContext.ItemsElementName = new ItemsChoiceType5[2] { ItemsChoiceType5.AuthnContextClassRef, ItemsChoiceType5.AuthnContextDeclRef }; statements.Add(sas); saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AuthnContextClassRef has a value which is not a wellformed absolute uri"); } /// /// Tests that AuthnStatement objects must have an valid uri content for AuthnContextDeclRef types /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthnContextDeclRef has a value which is not a wellformed absolute uri")] public void AuthnStatement_Invalid_AuthnContextDeclRefUri() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1234,14 +1291,15 @@ public void AuthnStatement_Invalid_AuthnContextDeclRefUri() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AuthnContextDeclRef has a value which is not a wellformed absolute uri"); } /// /// Tests that AuthnStatement objects MUST NOT have content of type AuthnContextDecl /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthnContextDecl elements are not allowed in this implementation")] public void AuthnStatement_Invalid_AuthnContextDecl() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1256,14 +1314,15 @@ public void AuthnStatement_Invalid_AuthnContextDecl() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AuthnContextDecl elements are not allowed in this implementation"); } /// /// Tests that AuthnStatement objects must have an valid uri content for AuthenticatingAuthority entries /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AuthenticatingAuthority array contains a value which is not a wellformed absolute uri")] public void AuthnStatement_Invalid_AuthnContextAuthenticatingAuthorityUri() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1279,14 +1338,15 @@ public void AuthnStatement_Invalid_AuthnContextAuthenticatingAuthorityUri() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AuthenticatingAuthority array contains a value which is not a wellformed absolute uri"); } /// /// Test that AttributeStatement objects must have a non-null Items-list /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AttributeStatement MUST contain at least one Attribute or EncryptedAttribute")] public void AttributeStatement_Invalid_NoAttributes() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1297,14 +1357,15 @@ public void AttributeStatement_Invalid_NoAttributes() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AttributeStatement MUST contain at least one Attribute or EncryptedAttribute"); } /// /// Test that AttributeStatement objects must have a non-empty Items-list /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "AttributeStatement MUST contain at least one Attribute or EncryptedAttribute")] public void AttributeStatement_Invalid_EmptyAttributes() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1315,14 +1376,15 @@ public void AttributeStatement_Invalid_EmptyAttributes() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "AttributeStatement MUST contain at least one Attribute or EncryptedAttribute"); } /// /// Test that Attribute objects must have a non-empty Name /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Name attribute of Attribute element MUST contain at least one non-whitespace character")] public void AttributeStatement_Invalid_Attribute() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); @@ -1333,27 +1395,30 @@ public void AttributeStatement_Invalid_Attribute() saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "Name attribute of Attribute element MUST contain at least one non-whitespace character"); } /// /// Test that xml attribute extensions on Attribute objects must be namespace qualified /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Attribute extension xml attributes MUST BE namespace qualified")] public void AttributeStatement_Invalid_Attribute_AnyAttrUnqualified() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); List statements = new List(saml20Assertion.Items); AttributeStatement sas = - (AttributeStatement)statements.Find(delegate(StatementAbstract ssa) { return ssa is AttributeStatement; }); + (AttributeStatement)statements.Find(delegate (StatementAbstract ssa) { return ssa is AttributeStatement; }); SamlAttribute sab = (SamlAttribute)sas.Items[0]; XmlDocument doc = new XmlDocument(); sab.AnyAttr = new XmlAttribute[1] { doc.CreateAttribute(String.Empty, "Nonqualified", String.Empty) }; saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "Attribute extension xml attributes MUST BE namespace qualified"); } /// @@ -1365,7 +1430,7 @@ public void AttributeStatement_Invalid_Attribute_AnyAttrSamlQualified() Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); List statements = new List(saml20Assertion.Items); AttributeStatement sas = - (AttributeStatement)statements.Find(delegate(StatementAbstract ssa) { return ssa is AttributeStatement; }); + (AttributeStatement)statements.Find(delegate (StatementAbstract ssa) { return ssa is AttributeStatement; }); SamlAttribute sab = (SamlAttribute)sas.Items[0]; XmlDocument doc = new XmlDocument(); saml20Assertion.Items = statements.ToArray(); @@ -1390,33 +1455,33 @@ public void AttributeStatement_Invalid_Attribute_AnyAttrSamlQualified() /// Test that EncryptedAttribute objects must have an EncryptedData child element /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "An EncryptedAttribute MUST contain an xenc:EncryptedData element")] public void AttributeStatement_Invalid_EncryptedAttribute_NoData() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); List statements = new List(saml20Assertion.Items); AttributeStatement sas = - (AttributeStatement)statements.Find(delegate(StatementAbstract ssa) { return ssa is AttributeStatement; }); + (AttributeStatement)statements.Find(delegate (StatementAbstract ssa) { return ssa is AttributeStatement; }); List attributes = new List(sas.Items); EncryptedElement ee = new EncryptedElement(); attributes.Add(ee); sas.Items = attributes.ToArray(); saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "An EncryptedAttribute MUST contain an xenc:EncryptedData element"); } /// /// Test that EncryptedData element must have the correct Type value /// [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Type attribute of EncryptedData MUST have value " + Saml20Constants.XENC + "Element" + " if it is present")] public void AttributeStatement_Invalid_EncryptedAttribute_WrongType() { Assertion saml20Assertion = AssertionUtil.GetBasicAssertion(); List statements = new List(saml20Assertion.Items); AttributeStatement sas = - (AttributeStatement)statements.Find(delegate(StatementAbstract ssa) { return ssa is AttributeStatement; }); + (AttributeStatement)statements.Find(delegate (StatementAbstract ssa) { return ssa is AttributeStatement; }); List attributes = new List(sas.Items); EncryptedElement ee = new EncryptedElement(); ee.encryptedData = new EncryptedData(); @@ -1425,29 +1490,33 @@ public void AttributeStatement_Invalid_EncryptedAttribute_WrongType() sas.Items = attributes.ToArray(); saml20Assertion.Items = statements.ToArray(); - CreateSaml20Token(saml20Assertion); + Assert.Throws( + () => CreateSaml20Token(saml20Assertion), + "Type attribute of EncryptedData MUST have value " + Saml20Constants.XENC + "Element" + " if it is present"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Resource attribute of AuthzDecisionStatement is REQUIRED")] public void AuthzDecisionStatement_Invalid_Resource() { AuthzDecisionStatement statement = new AuthzDecisionStatement(); Saml20StatementValidator validator = new Saml20StatementValidator(); statement.Resource = null; - validator.ValidateStatement(statement); + Assert.Throws( + () => validator.ValidateStatement(statement), + "Resource attribute of AuthzDecisionStatement is REQUIRED"); } [Test] - [ExpectedException(typeof(Saml20FormatException), ExpectedMessage = "Resource attribute of AuthzDecisionStatement has a value which is not a wellformed absolute uri")] public void AuthzDecisionStatement_Invalid_MalformedResource() { AuthzDecisionStatement statement = new AuthzDecisionStatement(); Saml20StatementValidator validator = new Saml20StatementValidator(); statement.Resource = "a malformed uri"; - validator.ValidateStatement(statement); + Assert.Throws( + () => validator.ValidateStatement(statement), + "Resource attribute of AuthzDecisionStatement has a value which is not a wellformed absolute uri"); } [Test] diff --git a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/SignatureTest.cs b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/SignatureTest.cs index cea48b9..1c70e8c 100644 --- a/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/SignatureTest.cs +++ b/src/dk.nita.saml20/dk.nita.test.saml20/Saml20/SignatureTest.cs @@ -45,7 +45,7 @@ public void VerifyManipulatedSignature() /// /// Deserializes the test tokens using the Safewhere DK-SAML class. /// - [Ignore] // TODO: test data needs fixing + [Ignore("test data needs fixing")] // TODO: test data needs fixing public void TestDKSaml20TokenVerification_01() { AssertionUtil.DeserializeToken(@"Saml20\Assertions\Saml2Assertion_01"); @@ -57,30 +57,33 @@ public void TestDKSaml20TokenVerification_01() /// Attempts to deserialize an invalid Saml-token. Tests that the Assertion class immediately "explodes". /// [Test] - [ExpectedException(typeof(Saml20Exception), ExpectedMessage = "Signature could not be verified.")] public void TestDKSaml20TokenVerification_02() { - AssertionUtil.DeserializeToken(@"Saml20\Assertions\EvilSaml2Assertion_01"); + Assert.Throws( + () => AssertionUtil.DeserializeToken(@"Saml20\Assertions\EvilSaml2Assertion_01"), + "Signature could not be verified."); } /// /// Attempts to deserialize an invalid Saml-token. Tests that the Assertion class immediately "explodes". /// [Test] - [ExpectedException(typeof(Saml20Exception), ExpectedMessage = "Signature could not be verified.")] public void TestDKSaml20TokenVerification_03() { - AssertionUtil.DeserializeToken(@"Saml20\Assertions\EvilSaml2Assertion_02"); + Assert.Throws( + () => AssertionUtil.DeserializeToken(@"Saml20\Assertions\EvilSaml2Assertion_02"), + "Signature could not be verified."); } /// /// Attempts to deserialize an invalid Saml-token. Tests that the Assertion class immediately "explodes". /// [Test] - [ExpectedException(typeof(Saml20Exception), ExpectedMessage = "Signature could not be verified.")] public void TestDKSaml20TokenVerification_04() { - AssertionUtil.DeserializeToken(@"Saml20\Assertions\EvilSaml2Assertion_03"); + Assert.Throws( + () => AssertionUtil.DeserializeToken(@"Saml20\Assertions\EvilSaml2Assertion_03"), + "Signature could not be verified."); } /// @@ -135,20 +138,26 @@ public void TestSigning_02() /// Test that the Assertion class verifies the signature of an assertion by default. /// [Test] - [ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Document does not contain a signature to verify.")] public void TestSigning_04() { // Any key-containing algorithm will do - the basic assertion is NOT signed anyway X509Certificate2 cert = new X509Certificate2(@"Saml20\Certificates\sts_dev_certificate.pfx", "test1234"); - new Saml20Assertion(AssertionUtil.GetTestAssertion_01().DocumentElement, new AsymmetricAlgorithm[] { cert.PublicKey.Key }, false); + + Assert.Throws( + () => + { + new Saml20Assertion(AssertionUtil.GetTestAssertion_01().DocumentElement, + new AsymmetricAlgorithm[] { cert.PublicKey.Key }, false); + }, + "Document does not contain a signature to verify."); } [Test] public void TestSHA256Signature() { - var xmlDocument = new XmlDocument {PreserveWhitespace = true}; + var xmlDocument = new XmlDocument { PreserveWhitespace = true }; xmlDocument.Load(@"Saml20\Assertions\SHA256Signedtest.xml"); Assert.IsTrue(XmlSignatureUtils.CheckSignature(xmlDocument)); } diff --git a/src/dk.nita.saml20/dk.nita.test.saml20/dk.nita.test.saml20.csproj b/src/dk.nita.saml20/dk.nita.test.saml20/dk.nita.test.saml20.csproj index b71f352..9895539 100644 --- a/src/dk.nita.saml20/dk.nita.test.saml20/dk.nita.test.saml20.csproj +++ b/src/dk.nita.saml20/dk.nita.test.saml20/dk.nita.test.saml20.csproj @@ -1,5 +1,6 @@  + Debug AnyCPU @@ -35,6 +36,8 @@ false true + + true @@ -119,8 +122,8 @@ false - - ..\packages\NUnit.2.6.4\lib\nunit.framework.dll + + ..\packages\NUnit.3.13.1\lib\net45\nunit.framework.dll @@ -240,6 +243,12 @@ + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + +