/// <summary> /// Validates the presence and correctness of a <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> among the any-xml-elements of a SubjectConfirmationData /// </summary> /// <param name="subjectConfirmationData">The subject confirmation data.</param> public void ValidateKeyInfo(SubjectConfirmationData subjectConfirmationData) { if (subjectConfirmationData == null) { throw new Saml20FormatException("SubjectConfirmationData cannot be null when KeyInfo subelements are required"); } if (subjectConfirmationData.AnyElements == null) { throw new Saml20FormatException(string.Format("SubjectConfirmationData element MUST have at least one {0} subelement", KeyInfo.ElementName)); } var keyInfoFound = false; foreach (var element in subjectConfirmationData.AnyElements) { if (element.NamespaceURI != Saml20Constants.Xmldsig || element.LocalName != KeyInfo.ElementName) { continue; } keyInfoFound = true; // A KeyInfo element MUST identify a cryptographic key if (!element.HasChildNodes) { throw new Saml20FormatException(string.Format("{0} subelement of SubjectConfirmationData MUST NOT be empty", KeyInfo.ElementName)); } } // There MUST BE at least one <ds:KeyInfo> element present (from the arbitrary elements list on SubjectConfirmationData if (!keyInfoFound) { throw new Saml20FormatException(string.Format("SubjectConfirmationData element MUST contain at least one {0} in namespace {1}", KeyInfo.ElementName, Saml20Constants.Xmldsig)); } }
/// <summary> /// Validate SubjectConfirmationData. /// </summary> /// <param name="subjectConfirmationData">The subject confirmation data.</param> /// <remarks> /// [SAML2.0 standard] section 2.4.1.2 /// </remarks> public void ValidateSubjectConfirmationData(SubjectConfirmationData subjectConfirmationData) { // If present it must be anyUri if (subjectConfirmationData.Recipient != null) { if (!Uri.IsWellFormedUriString(subjectConfirmationData.Recipient, UriKind.Absolute)) { throw new Saml20FormatException("Recipient of SubjectConfirmationData must be a wellformed absolute URI."); } } // NotBefore MUST BE striclty less than NotOnOrAfter if they are both set if (subjectConfirmationData.NotBefore != null && subjectConfirmationData.NotOnOrAfter != null && !(subjectConfirmationData.NotBefore < subjectConfirmationData.NotOnOrAfter)) { throw new Saml20FormatException(string.Format("NotBefore {0} MUST BE less than NotOnOrAfter {1} on SubjectConfirmationData", Saml20Utils.ToUtcString(subjectConfirmationData.NotBefore.Value), Saml20Utils.ToUtcString(subjectConfirmationData.NotOnOrAfter.Value))); } // Make sure the extension-attributes are namespace-qualified and do not use reserved namespaces if (subjectConfirmationData.AnyAttr != null) { _anyAttrValidator.ValidateXmlAnyAttributes(subjectConfirmationData.AnyAttr); } // Standards-defined extension type which has stricter rules than it's base type if (subjectConfirmationData is KeyInfoConfirmationData) { _keyInfoValidator.ValidateKeyInfo(subjectConfirmationData); } }
public void ValidatesSubjectConfirmationDataTimeIntervalSettings() { // TODO: Split this up // Arrange var validator = new Saml20SubjectConfirmationDataValidator(); var subjectConfirmationData = new SubjectConfirmationData(); subjectConfirmationData.NotBefore = new DateTime(2008, 01, 30, 17, 13, 0, 500, DateTimeKind.Utc); subjectConfirmationData.NotOnOrAfter = subjectConfirmationData.NotBefore.Value.AddHours(1); validator.ValidateSubjectConfirmationData(subjectConfirmationData); subjectConfirmationData.NotBefore = null; validator.ValidateSubjectConfirmationData(subjectConfirmationData); // DateTime validation wrt DateTime.UtcNow is NOT done by the validators // so a future-NotBefore must be valid subjectConfirmationData.NotBefore = subjectConfirmationData.NotOnOrAfter; subjectConfirmationData.NotOnOrAfter = null; validator.ValidateSubjectConfirmationData(subjectConfirmationData); subjectConfirmationData.NotBefore = null; // Act validator.ValidateSubjectConfirmationData(subjectConfirmationData); }
public void ValidatesSubjectConfirmationDataRecipient() { // Arrange var subjectConfirmationData = new SubjectConfirmationData { Recipient = "urn:wellformed.uri:ok" }; var validator = new Saml20SubjectConfirmationDataValidator(); // Act validator.ValidateSubjectConfirmationData(subjectConfirmationData); }
public void ThrowsExceptionWhenSubjectConfirmationDataTimeIntervalIsInvalid() { // Arrange var subjectConfirmationData = new SubjectConfirmationData(); subjectConfirmationData.NotBefore = new DateTime(2008, 01, 30, 17, 13, 0, 500, DateTimeKind.Utc); subjectConfirmationData.NotOnOrAfter = subjectConfirmationData.NotBefore.Value.AddHours(-1); var validator = new Saml20SubjectConfirmationDataValidator(); // Act validator.ValidateSubjectConfirmationData(subjectConfirmationData); }
public void ThrowsExceptionWhenSubjectConfirmationDataRecipientIsInvalid() { // Arrange var subjectConfirmationData = new SubjectConfirmationData { Recipient = "malformed uri" }; var validator = new Saml20SubjectConfirmationDataValidator(); // Act validator.ValidateSubjectConfirmationData(subjectConfirmationData); }