public void CheckTimeValidTest() { Saml2Serializer serializer = new Saml2Serializer(); SamlValidator validator = new SamlValidator(); Response response = serializer.ConvertXMLToResponseObject(ReadFile(xmlResponseFilename)); TimeZone localZone = TimeZone.CurrentTimeZone; DateTime actualTime = localZone.ToUniversalTime(DateTime.Now); try { // add a correct time to the response response.Assertion.Conditions.NotBefore = actualTime.AddSeconds(-20); response.Assertion.Conditions.NotOnOrAfter = actualTime.AddMinutes(5); response.Assertion.Subject.SubjectConfirmation.SubjectConfirmationData.NotOnOrAfter = actualTime.AddMinutes(5); response.IssueInstant = actualTime.AddSeconds(-20); response.Assertion.IssueInstant = actualTime.AddSeconds(-20); Assert.IsTrue(validator.CheckTime(response)); } catch (Exception e) { Assert.Fail(e.Message); } }
public void RoundTripSaml2(EnvelopedSignatureTheoryData theoryData) { var context = TestUtilities.WriteHeader($"{this}.RoundTripSaml2", theoryData); try { var serializer = new Saml2Serializer(); var samlAssertion = serializer.ReadAssertion(XmlUtilities.CreateDictionaryReader(theoryData.Xml)); var stream = new MemoryStream(); var writer = XmlDictionaryWriter.CreateTextWriter(stream); samlAssertion.SigningCredentials = theoryData.SigningCredentials; serializer.WriteAssertion(writer, samlAssertion); writer.Flush(); var xml = Encoding.UTF8.GetString(stream.ToArray()); samlAssertion.SigningCredentials = null; var samlAssertion2 = serializer.ReadAssertion(XmlUtilities.CreateDictionaryReader(xml)); samlAssertion2.Signature.Verify(theoryData.SigningCredentials.Key, theoryData.CryptoProviderFactory); IdentityComparer.AreEqual(samlAssertion, samlAssertion2, context); } catch (Exception ex) { theoryData.ExpectedException.ProcessException(ex, context); } TestUtilities.AssertFailIfErrors(context); }
public void RemoveEncryptedAssertionTest() { try { // https://docs.oasis-open.org/security/saml/v2.0/saml-schema-protocol-2.0.xsd Saml2Controller controller = new Saml2Controller(); Saml2Serializer serializer = new Saml2Serializer(); string keystorePath = ConfigurationManager.AppSettings.Get("KeystoreDirectoryPathSP") + ConfigurationManager.AppSettings.Get("KeystoreNameSP"); string keystorePassword = ConfigurationManager.AppSettings.Get("KeystorePasswordSP"); string friendlyName = ConfigurationManager.AppSettings.Get("KeystoreFriendlyNameSP"); string metadataDirectoryPath = ConfigurationManager.AppSettings.Get("MetadataDirectoryPath"); controller.Init(keystorePath, keystorePassword, friendlyName, metadataDirectoryPath); string xml = ReadFile(responseFilenameHub); Response response = serializer.ConvertXMLToResponseObject(xml); controller.RemoveEncryptedAssertion(response); Assert.IsNotNull(response.Assertion); } catch (Exception e) { Assert.Fail(e.Message); } }
public void GetAttributesTest() { string xml = ReadFile(xmlResponseFilename); Saml2Serializer saml = new Saml2Serializer(); Dictionary <string, ResponseAssertionAttribute> dictionary = saml.GetAttributes(xml); Assert.AreEqual("Max", dictionary["surname"].Values[0]); }
private void WriteRequestedSecurityToken(XmlWriter writer, Saml2SecurityToken token) { writer.WriteStartElement("t", "RequestedSecurityToken", WsTrust200502Namespace); Saml2Serializer serializer = new Saml2Serializer(); serializer.WriteAssertion(writer, token.Assertion); writer.WriteEndElement(); }
public void AuthnRequestObjectTest() { string xmlString = ReadFile(xmlFilename); Saml2Serializer saml = new Saml2Serializer(); AuthnRequest authnRequest = saml.ConvertXMLToAuthnRequestObject(xmlString); Assert.AreEqual("https://stiamhub:8443/Hub/SAML/SSO/Browser", authnRequest.Destination); Assert.AreEqual("http://localhost:14545/", authnRequest.AssertionConsumerServiceURL); Assert.AreEqual("hybridissuer.ch", authnRequest.Issuer); //Assert.AreEqual("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", authnRequest.NameIDPolicy.Format); }
public void ValidateResponseWithoutTimeValidTest() { Saml2Serializer serializer = new Saml2Serializer(); SamlValidator validator = new SamlValidator(); string xml = Encoding.UTF8.GetString(Convert.FromBase64String(ReadFile(responseFilename))); EntityDescriptor entityDescriptor = serializer.ConvertXMLToEntityDescriptorObject(ReadFile(xmlMetadataFile)); AuthnRequest authnRequest = serializer.ConvertXMLToAuthnRequestObject(ReadFile(xmlAuthnRequestFile)); Response response = serializer.ConvertXMLToResponseObject(xml); bool isValid = validator.ValidateResponse(response, xml, entityDescriptor, authnRequest, false); Assert.IsTrue(isValid); }
public void CheckAuthnRequestGenerationTest() { string xmlString = ReadFile(xmlFilename); Saml2Serializer saml = new Saml2Serializer(); string original; string zipped = saml.Deflate(xmlString, out original); string unzipped = saml.Inflate(zipped); Assert.AreEqual(original, unzipped); // result: fZLLTsMwEEV/xfI+OCkONKOmUqBCrVRo1RQWbJCTOMQosYPHAfr3uClILFA3XszcOXcenqHo2kkP2eAavZPvg0RHMkRpnTL61mgcOmlzaT9UKR9365Q2zvXA2FsPEY95zChZ+BqlxbHglEaf9yHRNUMBU84v2XIoWJ7dr1meb9iNNZ/egJI7Y0s5Oqe0Fi1KSlaLlL5UCZ9Gk6QOoujqOuCFqALh34Anop6G0+uaR7GXIg5ypdEJ7VI6CaOrIAqDiO/DGPglhOFFksTPlGytcaY07Y3SldKvKR2sBiNQIWjRSQRXwrE3mFyEUJxECMv9fhtsN/mekidpcZzNCyj56lqNcFrbeVb/Y0zJnMzGAhh7tn8Z5xHi9xJ03hwKqyo1AmbsL+6X3sODB6wWW9Oq8kCytjWft1YKJ1Pq7CDHhXfCnbc8RlQV1KMU+uPs6KR2lDBvxP75L/Nv }
public void CreateAuthnRequstTest() { string xmlString = ReadFile(xmlFilename); Saml2Serializer saml = new Saml2Serializer(); Cryptography crypto = new Cryptography(); Saml2AuthnRequest authn = new Saml2AuthnRequest(); AuthnRequest authnRequest = saml.ConvertXMLToAuthnRequestObject(xmlString); authn.AssertionConsumerServiceURL = authnRequest.AssertionConsumerServiceURL; authn.AttributeConsumingServiceIndex = authnRequest.AttributeConsumingServiceIndex; authn.Destination = authnRequest.Destination; authn.ForceAuthn = authnRequest.ForceAuthn; authn.Issuer = authnRequest.Issuer; authn.ProviderName = "HybridIssuer"; TimeZone localZone = TimeZone.CurrentTimeZone; authn.IssueInstant = localZone.ToUniversalTime(DateTime.Now); authn.ID = "65464-6546-6454889-3313"; string original; string zipped = saml.Deflate(authn.ToXML(), out original); string sigAlg = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; // SAMLResponse=value&RelayState=value&SigAlg=value string toSign = "SAMLRequest=" + HttpUtility.UrlEncode(zipped, Encoding.UTF8) + "&RelayState=" + HttpUtility.UrlEncode("34bad366-f60b-4491-a462-230ea22423ad", Encoding.UTF8) + "&SigAlg=" + HttpUtility.UrlEncode(sigAlg, Encoding.UTF8); //byte[] sig = saml.SignXML(xmlString); //string signature = Convert.ToBase64String(sig); string keystorePath = AppDomain.CurrentDomain.BaseDirectory + "\\Keys\\hybridissuer.pfx"; string keystorePassword = "******"; string friendlyName = "hybridissuer"; SamlCertificateController certController = new SamlCertificateController(); X509Certificate2 cert = certController.GetCertificate(friendlyName, keystorePath, keystorePassword); string signature = crypto.SignString(toSign, cert, Cryptography.SigningAlgorithm.SHA1withRSA); string request = authnRequest.Destination + "?" + toSign + "&Signature=" + HttpUtility.UrlEncode(signature, Encoding.UTF8); }
public void Serialize(XmlWriter writer, SamlResponseMessage response) { if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (response == null) { throw new ArgumentNullException(nameof(response)); } writer.WriteStartElement("samlp", response.ResponseType, SamlProtocolNamespace); writer.WriteAttributeString("IssueInstant", XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)); writer.WriteAttributeString("ID", "_" + response.Id); writer.WriteAttributeString("Version", "2.0"); writer.WriteAttributeString("Destination", response.ReplyTo.ToString()); if (!string.IsNullOrWhiteSpace(response.InResponseTo)) { writer.WriteAttributeString("InResponseTo", response.InResponseTo); } writer.WriteStartElement("Issuer", Saml2Namespace); writer.WriteString(response.Issuer); writer.WriteEndElement(); writer.WriteStartElement("samlp", "Status", SamlProtocolNamespace); writer.WriteStartElement("samlp", "StatusCode", SamlProtocolNamespace); writer.WriteAttributeString("Value", "urn:oasis:names:tc:SAML:2.0:status:Success"); writer.WriteEndElement(); writer.WriteEndElement(); if (response.Token != null) { Saml2Serializer serializer = new Saml2Serializer(); serializer.WriteAssertion(writer, response.Token.Assertion); } writer.WriteEndElement(); }
public void RoundTripSamlPSignatureAfterAssertion() { var context = new CompareContext($"{this}.RoundTripSamlPSignatureAfterAssertion"); ExpectedException expectedException = ExpectedException.NoExceptionExpected; var samlpTokenKey = KeyingMaterial.RsaSigningCreds_4096_Public.Key; var samlpTokenSigningCredentials = KeyingMaterial.RsaSigningCreds_4096; var samlpKey = KeyingMaterial.RsaSigningCreds_2048_Public.Key; var samlpSigningCredentials = KeyingMaterial.RsaSigningCreds_2048; try { // write samlp var settings = new XmlWriterSettings { Encoding = new UTF8Encoding(false) }; var buffer = new MemoryStream(); var esw = new EnvelopedSignatureWriter(XmlWriter.Create(buffer, settings), samlpSigningCredentials, "id-uAOhNLe7abGB6WGPk"); esw.WriteStartElement("ns0", "Response", "urn:oasis:names:tc:SAML:2.0:protocol"); esw.WriteAttributeString("ns1", "urn:oasis:names:tc:SAML:2.0:assertion"); esw.WriteAttributeString("ns2", "http://www.w3.org/2000/09/xmldsig#"); esw.WriteAttributeString("Destination", "https://tnia.eidentita.cz/fpsts/processRequest.aspx"); esw.WriteAttributeString("ID", "id-uAOhNLe7abGB6WGPk"); esw.WriteAttributeString("InResponseTo", "ida5714d006fcc430c92aacf34ab30b166"); esw.WriteAttributeString("IssueInstant", "2019-04-08T10:30:49Z"); esw.WriteAttributeString("Version", "2.0"); esw.WriteStartElement("ns1", "Issuer"); esw.WriteAttributeString("Format", "urn:oasis:names:tc:SAML:2.0:nameid-format:entity"); esw.WriteString("https://mojeid.regtest.nic.cz/saml/idp.xml"); esw.WriteEndElement(); esw.WriteStartElement("ns0", "Status", null); esw.WriteStartElement("ns0", "StatusCode", null); esw.WriteAttributeString("Value", "urn:oasis:names:tc:SAML:2.0:status:Success"); esw.WriteEndElement(); esw.WriteEndElement(); Saml2Serializer samlSerializer = new Saml2Serializer(); Saml2Assertion assertion = CreateAssertion(samlpTokenSigningCredentials); samlSerializer.WriteAssertion(esw, assertion); esw.WriteSignature(); esw.WriteEndElement(); var xml = Encoding.UTF8.GetString(buffer.ToArray()); // read samlp and verify signatures XmlReader reader = XmlUtilities.CreateDictionaryReader(xml); IXmlElementReader tokenReaders = new TokenReaders(new List <SecurityTokenHandler> { new Saml2SecurityTokenHandler() }); EnvelopedSignatureReader envelopedReader = new EnvelopedSignatureReader(reader, tokenReaders); while (envelopedReader.Read()) { ; } foreach (var item in tokenReaders.Items) { if (item is Saml2SecurityToken samlToken) { samlToken.Assertion.Signature.Verify(samlpTokenKey); } } envelopedReader.Signature.Verify(samlpKey, samlpKey.CryptoProviderFactory); expectedException.ProcessNoException(context); } catch (Exception ex) { expectedException.ProcessException(ex, context); } TestUtilities.AssertFailIfErrors(context); }
public void CheckTimeInvalidTest() { Saml2Serializer serializer = new Saml2Serializer(); SamlValidator validator = new SamlValidator(); Response response = serializer.ConvertXMLToResponseObject(ReadFile(xmlResponseFilename)); TimeZone localZone = TimeZone.CurrentTimeZone; DateTime actualTime = localZone.ToUniversalTime(DateTime.Now); // response.Assertion.Conditions.NotBefore is wrong try { response.Assertion.Conditions.NotBefore = actualTime.AddSeconds(20); response.Assertion.Conditions.NotOnOrAfter = actualTime.AddMinutes(5); response.Assertion.Subject.SubjectConfirmation.SubjectConfirmationData.NotOnOrAfter = actualTime.AddMinutes(5); response.IssueInstant = actualTime.AddSeconds(-20); response.Assertion.IssueInstant = actualTime.AddSeconds(-20); Assert.IsFalse(validator.CheckTime(response)); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // response.Assertion.Conditions.NotOnOrAfter is wrong try { response.Assertion.Conditions.NotBefore = actualTime.AddSeconds(-20); response.Assertion.Conditions.NotOnOrAfter = actualTime.AddMinutes(-20); response.Assertion.Subject.SubjectConfirmation.SubjectConfirmationData.NotOnOrAfter = actualTime.AddMinutes(5); response.IssueInstant = actualTime.AddSeconds(-20); response.Assertion.IssueInstant = actualTime.AddSeconds(-20); Assert.IsFalse(validator.CheckTime(response)); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // response.Assertion.Subject.SubjectConfirmation.SubjectConfirmationData.NotOnOrAfter is wrong try { response.Assertion.Conditions.NotBefore = actualTime.AddSeconds(-20); response.Assertion.Conditions.NotOnOrAfter = actualTime.AddMinutes(5); response.Assertion.Subject.SubjectConfirmation.SubjectConfirmationData.NotOnOrAfter = actualTime.AddMinutes(-20); response.IssueInstant = actualTime.AddSeconds(-20); response.Assertion.IssueInstant = actualTime.AddSeconds(-20); Assert.IsFalse(validator.CheckTime(response)); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // response.IssueInstant is wrong try { response.Assertion.Conditions.NotBefore = actualTime.AddSeconds(-20); response.Assertion.Conditions.NotOnOrAfter = actualTime.AddMinutes(5); response.Assertion.Subject.SubjectConfirmation.SubjectConfirmationData.NotOnOrAfter = actualTime.AddMinutes(5); response.IssueInstant = actualTime.AddSeconds(20); response.Assertion.IssueInstant = actualTime.AddSeconds(-20); Assert.IsFalse(validator.CheckTime(response)); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // response.Assertion.IssueInstant is wrong try { response.Assertion.Conditions.NotBefore = actualTime.AddSeconds(-20); response.Assertion.Conditions.NotOnOrAfter = actualTime.AddMinutes(5); response.Assertion.Subject.SubjectConfirmation.SubjectConfirmationData.NotOnOrAfter = actualTime.AddMinutes(5); response.IssueInstant = actualTime.AddSeconds(-20); response.Assertion.IssueInstant = actualTime.AddSeconds(20); Assert.IsFalse(validator.CheckTime(response)); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected }
public void ValidateResponseWithoutTimeInvalidTest() { Saml2Serializer serializer = new Saml2Serializer(); SamlValidator validator = new SamlValidator(); string xml = ReadFile(xmlResponseFilename); EntityDescriptor entityDescriptor = serializer.ConvertXMLToEntityDescriptorObject(ReadFile(xmlMetadataFile)); AuthnRequest authnRequest = serializer.ConvertXMLToAuthnRequestObject(ReadFile(xmlAuthnRequestFile)); Response response = serializer.ConvertXMLToResponseObject(xml); // wrong response.Status.StatusCode.Value try { response.Status.StatusCode.Value = "urn:oasis:names:tc:SAML:2.0:status:Requester"; bool isValid = validator.ValidateResponse(response, xml, entityDescriptor, authnRequest, false); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // wrong response.Issuer try { response.Issuer = "wrongIssuer"; bool isValid = validator.ValidateResponse(response, xml, entityDescriptor, authnRequest, false); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // wrong x509 certificate try { response.Signature.KeyInfo.X509Data.X509Certificate = response.Signature.KeyInfo.X509Data.X509Certificate + "s"; bool isValid = validator.ValidateResponse(response, xml, entityDescriptor, authnRequest, false); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // response was changed / attack try { string attackedXML = ReadFile("ChangedSamlResponseSimpleSamlPHP.xml"); response.Signature.KeyInfo.X509Data.X509Certificate = response.Signature.KeyInfo.X509Data.X509Certificate + "s"; bool isValid = validator.ValidateResponse(response, attackedXML, entityDescriptor, authnRequest, false); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // wrong response.Destination try { response.Destination = "newdesinationaddress.com"; bool isValid = validator.ValidateResponse(response, xml, entityDescriptor, authnRequest, false); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // wrong response.Assertion.Conditions.AudienceRestriction.Audience -> issuer try { response.Assertion.Conditions.AudienceRestriction.Audience = "otherIssuer"; bool isValid = validator.ValidateResponse(response, xml, entityDescriptor, authnRequest, false); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // wrong response.InResponseTo try { response.InResponseTo = "InResponseTo"; bool isValid = validator.ValidateResponse(response, xml, entityDescriptor, authnRequest, false); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected // wrong response.Assertion.Subject.SubjectConfirmation.Method try { response.Assertion.Subject.SubjectConfirmation.Method = "urn:oasis:names:tc:SAML:2.0:cm:holder-of-key"; bool isValid = validator.ValidateResponse(response, xml, entityDescriptor, authnRequest, false); } catch (SamlCommunicationException e) { Assert.IsTrue(true); } // exception expected in this test catch (Exception e) { Assert.Fail(e.Message); } // not this kind of exception expected }
public SolidSaml2SecurityTokenHandler(Saml2Serializer serializer) : base() { }
public FederationMetadataSerializer(WsAuthorizationSerializer wsAuthorizationSerializer, WsAddressingSerializer wsAddressingSerializer, Saml2Serializer saml2Serializer, DSigSerializer dSigSerializer) : base(saml2Serializer, dSigSerializer) { WsAuthorizationSerializer = wsAuthorizationSerializer; WsAddressingSerializer = wsAddressingSerializer; }