private Collection <XmlElement> NormalizeAdditionalParameters(Collection <XmlElement> additionalParameters, TrustDriver driver, bool clientSideClaimTypeRequirementsSpecified) { // Ensure STS trust version is one of the currently supported versions: Feb 05 / Trust 1.3 Fx.Assert(((driver.StandardsManager.TrustVersion == TrustVersion.WSTrustFeb2005) || (driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13)), "Unsupported trust version specified for the STS."); // We have a mismatch. Make a local copy of additionalParameters for making any potential modifications // as part of normalization Collection <XmlElement> tmpCollection = new Collection <XmlElement>(); foreach (XmlElement e in additionalParameters) { tmpCollection.Add(e); } // 1. For Trust 1.3 EncryptionAlgorithm, CanonicalizationAlgorithm and KeyWrapAlgorithm should not be // specified as top-level element if "SecondaryParameters" element already specifies this. if (driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13) { Fx.Assert(driver.GetType() == typeof(WSTrustDec2005.DriverDec2005), "Invalid Trust Driver specified for Trust 1.3."); XmlElement encryptionAlgorithmElement = null; XmlElement canonicalizationAlgorithmElement = null; XmlElement keyWrapAlgorithmElement = null; XmlElement secondaryParameter = null; for (int i = 0; i < tmpCollection.Count; ++i) { if (driver.IsEncryptionAlgorithmElement(tmpCollection[i], out string algorithm)) { encryptionAlgorithmElement = tmpCollection[i]; } else if (driver.IsCanonicalizationAlgorithmElement(tmpCollection[i], out algorithm)) { canonicalizationAlgorithmElement = tmpCollection[i]; } else if (driver.IsKeyWrapAlgorithmElement(tmpCollection[i], out algorithm)) { keyWrapAlgorithmElement = tmpCollection[i]; } else if (((WSTrustDec2005.DriverDec2005)driver).IsSecondaryParametersElement(tmpCollection[i])) { secondaryParameter = tmpCollection[i]; } } if (secondaryParameter != null) { foreach (XmlNode node in secondaryParameter.ChildNodes) { if (node is XmlElement child) { if (driver.IsEncryptionAlgorithmElement(child, out string algorithm) && (encryptionAlgorithmElement != null)) { tmpCollection.Remove(encryptionAlgorithmElement); } else if (driver.IsCanonicalizationAlgorithmElement(child, out algorithm) && (canonicalizationAlgorithmElement != null)) { tmpCollection.Remove(canonicalizationAlgorithmElement); } else if (driver.IsKeyWrapAlgorithmElement(child, out algorithm) && (keyWrapAlgorithmElement != null)) { tmpCollection.Remove(keyWrapAlgorithmElement); } } } } } // 2. Check for Mismatch. // a. Trust Feb 2005 -> Trust 1.3. do the following, // (i) Copy EncryptionAlgorithm and CanonicalizationAlgorithm as the top-level elements. // Note, this is in contradiction to step 1. But we don't have a choice here as we cannot say from the // Additional Parameters section in the config what came from the service and what came from the client. // (ii) Convert SignWith and EncryptWith elements to Trust 1.3 namespace. // b. For Trust 1.3 -> Trust Feb 2005, do the following, // (i) Find EncryptionAlgorithm, CanonicalizationAlgorithm from inside the "SecondaryParameters" element. // If found, then promote these as the top-level elements replacing the existing values. // (ii) Convert the SignWith and EncryptWith elements to the Trust Feb 2005 namespace and drop the KeyWrapAlgorithm // element. // make an optimistic check to detect mismatched trust-versions between STS and RP bool mismatch = (((driver.StandardsManager.TrustVersion == TrustVersion.WSTrustFeb2005) && !CollectionContainsElementsWithTrustNamespace(additionalParameters, TrustFeb2005Strings.Namespace)) || ((driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13) && !CollectionContainsElementsWithTrustNamespace(additionalParameters, TrustDec2005Strings.Namespace))); // if no mismatch, return unmodified collection if (!mismatch) { return(tmpCollection); } // 2.a // If we are talking to a Trust 1.3 STS, replace any Feb '05 algorithm parameters with their Trust 1.3 counterparts if (driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13) { SecurityStandardsManager trustFeb2005StandardsManager = SecurityStandardsManager.DefaultInstance; // the following cast is guaranteed to succeed WSTrustFeb2005.DriverFeb2005 trustFeb2005Driver = (WSTrustFeb2005.DriverFeb2005)trustFeb2005StandardsManager.TrustDriver; for (int i = 0; i < tmpCollection.Count; i++) { if (trustFeb2005Driver.IsSignWithElement(tmpCollection[i], out string algorithmParameter)) { tmpCollection[i] = driver.CreateSignWithElement(algorithmParameter); } else if (trustFeb2005Driver.IsEncryptWithElement(tmpCollection[i], out algorithmParameter)) { tmpCollection[i] = driver.CreateEncryptWithElement(algorithmParameter); } else if (trustFeb2005Driver.IsEncryptionAlgorithmElement(tmpCollection[i], out algorithmParameter)) { tmpCollection[i] = driver.CreateEncryptionAlgorithmElement(algorithmParameter); } else if (trustFeb2005Driver.IsCanonicalizationAlgorithmElement(tmpCollection[i], out algorithmParameter)) { tmpCollection[i] = driver.CreateCanonicalizationAlgorithmElement(algorithmParameter); } } } else { // 2.b // We are talking to a Feb 05 STS. Filter out any SecondaryParameters element. Collection <XmlElement> childrenToPromote = null; WSSecurityTokenSerializer trust13Serializer = new WSSecurityTokenSerializer(SecurityVersion.WSSecurity11, TrustVersion.WSTrust13, SecureConversationVersion.WSSecureConversation13, true, null, null, null); SecurityStandardsManager trust13StandardsManager = new SecurityStandardsManager(MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12, trust13Serializer); // the following cast is guaranteed to succeed WSTrustDec2005.DriverDec2005 trust13Driver = (WSTrustDec2005.DriverDec2005)trust13StandardsManager.TrustDriver; foreach (XmlElement parameter in tmpCollection) { // check if SecondaryParameters is present if (trust13Driver.IsSecondaryParametersElement(parameter)) { childrenToPromote = new Collection <XmlElement>(); // walk SecondaryParameters and collect any 'non-standard' children foreach (XmlNode innerNode in parameter.ChildNodes) { if ((innerNode is XmlElement innerElement) && CanPromoteToRoot(innerElement, trust13Driver, clientSideClaimTypeRequirementsSpecified)) { childrenToPromote.Add(innerElement); } } // remove SecondaryParameters element tmpCollection.Remove(parameter); // we are done - break out of the loop break; } } // Probe of standard Trust elements and remember them. if ((childrenToPromote != null) && (childrenToPromote.Count > 0)) { XmlElement encryptionElement = null; XmlElement canonicalizationElement = null; XmlElement requiredClaimsElement = null; Collection <XmlElement> processedElements = new Collection <XmlElement>(); foreach (XmlElement e in childrenToPromote) { if ((encryptionElement == null) && trust13Driver.IsEncryptionAlgorithmElement(e, out string encryptionAlgorithm)) { encryptionElement = driver.CreateEncryptionAlgorithmElement(encryptionAlgorithm); processedElements.Add(e); } else if ((canonicalizationElement == null) && trust13Driver.IsCanonicalizationAlgorithmElement(e, out string canonicalizationAlgoritm)) { canonicalizationElement = driver.CreateCanonicalizationAlgorithmElement(canonicalizationAlgoritm); processedElements.Add(e); } else if ((requiredClaimsElement == null) && trust13Driver.TryParseRequiredClaimsElement(e, out Collection <XmlElement> requiredClaims)) { requiredClaimsElement = driver.CreateRequiredClaimsElement(requiredClaims); processedElements.Add(e); } } for (int i = 0; i < processedElements.Count; ++i) { childrenToPromote.Remove(processedElements[i]); } XmlElement keyWrapAlgorithmElement = null; // Replace the appropriate elements. for (int i = 0; i < tmpCollection.Count; ++i) { if (trust13Driver.IsSignWithElement(tmpCollection[i], out string algorithmParameter)) { tmpCollection[i] = driver.CreateSignWithElement(algorithmParameter); } else if (trust13Driver.IsEncryptWithElement(tmpCollection[i], out algorithmParameter)) { tmpCollection[i] = driver.CreateEncryptWithElement(algorithmParameter); } else if (trust13Driver.IsEncryptionAlgorithmElement(tmpCollection[i], out algorithmParameter) && (encryptionElement != null)) { tmpCollection[i] = encryptionElement; encryptionElement = null; } else if (trust13Driver.IsCanonicalizationAlgorithmElement(tmpCollection[i], out algorithmParameter) && (canonicalizationElement != null)) { tmpCollection[i] = canonicalizationElement; canonicalizationElement = null; } else if (trust13Driver.IsKeyWrapAlgorithmElement(tmpCollection[i], out algorithmParameter) && (keyWrapAlgorithmElement == null)) { keyWrapAlgorithmElement = tmpCollection[i]; } else if (trust13Driver.TryParseRequiredClaimsElement(tmpCollection[i], out Collection <XmlElement> reqClaims) && (requiredClaimsElement != null)) { tmpCollection[i] = requiredClaimsElement; requiredClaimsElement = null; } } if (keyWrapAlgorithmElement != null) { // Remove KeyWrapAlgorithmElement as this is not define in Trust Feb 2005. tmpCollection.Remove(keyWrapAlgorithmElement); } // Add the remaining elements to the additionaParameters list to the end. if (encryptionElement != null) { tmpCollection.Add(encryptionElement); } if (canonicalizationElement != null) { tmpCollection.Add(canonicalizationElement); } if (requiredClaimsElement != null) { tmpCollection.Add(requiredClaimsElement); } if (childrenToPromote.Count > 0) { // There are some non-standard elements. Just bump them to the top-level element. for (int i = 0; i < childrenToPromote.Count; ++i) { tmpCollection.Add(childrenToPromote[i]); } } } } return(tmpCollection); }
private Collection<XmlElement> NormalizeAdditionalParameters(Collection<XmlElement> additionalParameters, TrustDriver driver, bool clientSideClaimTypeRequirementsSpecified) { // Ensure STS trust version is one of the currently supported versions: Feb 05 / Trust 1.3 Fx.Assert(((driver.StandardsManager.TrustVersion == TrustVersion.WSTrustFeb2005) || (driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13)), "Unsupported trust version specified for the STS."); // We have a mismatch. Make a local copy of additionalParameters for making any potential modifications // as part of normalization Collection<XmlElement> tmpCollection = new Collection<XmlElement>(); foreach (XmlElement e in additionalParameters) { tmpCollection.Add(e); } // 1. For Trust 1.3 EncryptionAlgorithm, CanonicalizationAlgorithm and KeyWrapAlgorithm should not be // specified as top-level element if "SecondaryParameters" element already specifies this. if (driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13) { Fx.Assert(driver.GetType() == typeof(WSTrustDec2005.DriverDec2005), "Invalid Trust Driver specified for Trust 1.3."); XmlElement encryptionAlgorithmElement = null; XmlElement canonicalizationAlgorithmElement = null; XmlElement keyWrapAlgorithmElement = null; XmlElement secondaryParameter = null; for (int i = 0; i < tmpCollection.Count; ++i) { string algorithm; if (driver.IsEncryptionAlgorithmElement(tmpCollection[i], out algorithm)) { encryptionAlgorithmElement = tmpCollection[i]; } else if (driver.IsCanonicalizationAlgorithmElement(tmpCollection[i], out algorithm)) { canonicalizationAlgorithmElement = tmpCollection[i]; } else if (driver.IsKeyWrapAlgorithmElement(tmpCollection[i], out algorithm)) { keyWrapAlgorithmElement = tmpCollection[i]; } else if (((WSTrustDec2005.DriverDec2005)driver).IsSecondaryParametersElement(tmpCollection[i])) { secondaryParameter = tmpCollection[i]; } } if (secondaryParameter != null) { foreach (XmlNode node in secondaryParameter.ChildNodes) { XmlElement child = node as XmlElement; if (child != null) { string algorithm = null; if (driver.IsEncryptionAlgorithmElement(child, out algorithm) && (encryptionAlgorithmElement != null)) { tmpCollection.Remove(encryptionAlgorithmElement); } else if (driver.IsCanonicalizationAlgorithmElement(child, out algorithm) && (canonicalizationAlgorithmElement != null)) { tmpCollection.Remove(canonicalizationAlgorithmElement); } else if (driver.IsKeyWrapAlgorithmElement(child, out algorithm) && (keyWrapAlgorithmElement != null)) { tmpCollection.Remove(keyWrapAlgorithmElement); } } } } } // 2. Check for Mismatch. // a. Trust Feb 2005 -> Trust 1.3. do the following, // (i) Copy EncryptionAlgorithm and CanonicalizationAlgorithm as the top-level elements. // Note, this is in contradiction to step 1. But we don't have a choice here as we cannot say from the // Additional Parameters section in the config what came from the service and what came from the client. // (ii) Convert SignWith and EncryptWith elements to Trust 1.3 namespace. // b. For Trust 1.3 -> Trust Feb 2005, do the following, // (i) Find EncryptionAlgorithm, CanonicalizationAlgorithm from inside the "SecondaryParameters" element. // If found, then promote these as the top-level elements replacing the existing values. // (ii) Convert the SignWith and EncryptWith elements to the Trust Feb 2005 namespace and drop the KeyWrapAlgorithm // element. // make an optimistic check to detect mismatched trust-versions between STS and RP bool mismatch = (((driver.StandardsManager.TrustVersion == TrustVersion.WSTrustFeb2005) && !CollectionContainsElementsWithTrustNamespace(additionalParameters, TrustFeb2005Strings.Namespace)) || ((driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13) && !CollectionContainsElementsWithTrustNamespace(additionalParameters, TrustDec2005Strings.Namespace))); // if no mismatch, return unmodified collection if (!mismatch) { return tmpCollection; } // 2.a // If we are talking to a Trust 1.3 STS, replace any Feb '05 algorithm parameters with their Trust 1.3 counterparts if (driver.StandardsManager.TrustVersion == TrustVersion.WSTrust13) { SecurityStandardsManager trustFeb2005StandardsManager = SecurityStandardsManager.DefaultInstance; // the following cast is guaranteed to succeed WSTrustFeb2005.DriverFeb2005 trustFeb2005Driver = (WSTrustFeb2005.DriverFeb2005)trustFeb2005StandardsManager.TrustDriver; for (int i = 0; i < tmpCollection.Count; i++) { string algorithmParameter = string.Empty; if (trustFeb2005Driver.IsSignWithElement(tmpCollection[i], out algorithmParameter)) { tmpCollection[i] = driver.CreateSignWithElement(algorithmParameter); } else if (trustFeb2005Driver.IsEncryptWithElement(tmpCollection[i], out algorithmParameter)) { tmpCollection[i] = driver.CreateEncryptWithElement(algorithmParameter); } else if (trustFeb2005Driver.IsEncryptionAlgorithmElement(tmpCollection[i], out algorithmParameter)) { tmpCollection[i] = driver.CreateEncryptionAlgorithmElement(algorithmParameter); } else if (trustFeb2005Driver.IsCanonicalizationAlgorithmElement(tmpCollection[i], out algorithmParameter)) { tmpCollection[i] = driver.CreateCanonicalizationAlgorithmElement(algorithmParameter); } } } else { // 2.b // We are talking to a Feb 05 STS. Filter out any SecondaryParameters element. Collection<XmlElement> childrenToPromote = null; WSSecurityTokenSerializer trust13Serializer = new WSSecurityTokenSerializer(SecurityVersion.WSSecurity11, TrustVersion.WSTrust13, SecureConversationVersion.WSSecureConversation13, true, null, null, null); SecurityStandardsManager trust13StandardsManager = new SecurityStandardsManager(MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12, trust13Serializer); // the following cast is guaranteed to succeed WSTrustDec2005.DriverDec2005 trust13Driver = (WSTrustDec2005.DriverDec2005)trust13StandardsManager.TrustDriver; foreach (XmlElement parameter in tmpCollection) { // check if SecondaryParameters is present if (trust13Driver.IsSecondaryParametersElement(parameter)) { childrenToPromote = new Collection<XmlElement>(); // walk SecondaryParameters and collect any 'non-standard' children foreach (XmlNode innerNode in parameter.ChildNodes) { XmlElement innerElement = innerNode as XmlElement; if ((innerElement != null) && CanPromoteToRoot(innerElement, trust13Driver, clientSideClaimTypeRequirementsSpecified)) { childrenToPromote.Add(innerElement); } } // remove SecondaryParameters element tmpCollection.Remove(parameter); // we are done - break out of the loop break; } } // Probe of standard Trust elements and remember them. if ((childrenToPromote != null) && (childrenToPromote.Count > 0)) { XmlElement encryptionElement = null; string encryptionAlgorithm = String.Empty; XmlElement canonicalizationElement = null; string canonicalizationAlgoritm = String.Empty; XmlElement requiredClaimsElement = null; Collection<XmlElement> requiredClaims = null; Collection<XmlElement> processedElements = new Collection<XmlElement>(); foreach (XmlElement e in childrenToPromote) { if ((encryptionElement == null) && trust13Driver.IsEncryptionAlgorithmElement(e, out encryptionAlgorithm)) { encryptionElement = driver.CreateEncryptionAlgorithmElement(encryptionAlgorithm); processedElements.Add(e); } else if ((canonicalizationElement == null) && trust13Driver.IsCanonicalizationAlgorithmElement(e, out canonicalizationAlgoritm)) { canonicalizationElement = driver.CreateCanonicalizationAlgorithmElement(canonicalizationAlgoritm); processedElements.Add(e); } else if ((requiredClaimsElement == null) && trust13Driver.TryParseRequiredClaimsElement(e, out requiredClaims)) { requiredClaimsElement = driver.CreateRequiredClaimsElement(requiredClaims); processedElements.Add(e); } } for (int i = 0; i < processedElements.Count; ++i) { childrenToPromote.Remove(processedElements[i]); } XmlElement keyWrapAlgorithmElement = null; // Replace the appropriate elements. for (int i = 0; i < tmpCollection.Count; ++i) { string algorithmParameter; Collection<XmlElement> reqClaims; if (trust13Driver.IsSignWithElement(tmpCollection[i], out algorithmParameter)) { tmpCollection[i] = driver.CreateSignWithElement(algorithmParameter); } else if (trust13Driver.IsEncryptWithElement(tmpCollection[i], out algorithmParameter)) { tmpCollection[i] = driver.CreateEncryptWithElement(algorithmParameter); } else if (trust13Driver.IsEncryptionAlgorithmElement(tmpCollection[i], out algorithmParameter) && (encryptionElement != null)) { tmpCollection[i] = encryptionElement; encryptionElement = null; } else if (trust13Driver.IsCanonicalizationAlgorithmElement(tmpCollection[i], out algorithmParameter) && (canonicalizationElement != null)) { tmpCollection[i] = canonicalizationElement; canonicalizationElement = null; } else if (trust13Driver.IsKeyWrapAlgorithmElement(tmpCollection[i], out algorithmParameter) && (keyWrapAlgorithmElement == null)) { keyWrapAlgorithmElement = tmpCollection[i]; } else if (trust13Driver.TryParseRequiredClaimsElement(tmpCollection[i], out reqClaims) && (requiredClaimsElement != null)) { tmpCollection[i] = requiredClaimsElement; requiredClaimsElement = null; } } if (keyWrapAlgorithmElement != null) { // Remove KeyWrapAlgorithmElement as this is not define in Trust Feb 2005. tmpCollection.Remove(keyWrapAlgorithmElement); } // Add the remaining elements to the additionaParameters list to the end. if (encryptionElement != null) tmpCollection.Add(encryptionElement); if (canonicalizationElement != null) tmpCollection.Add(canonicalizationElement); if (requiredClaimsElement != null) tmpCollection.Add(requiredClaimsElement); if (childrenToPromote.Count > 0) { // There are some non-standard elements. Just bump them to the top-level element. for (int i = 0; i < childrenToPromote.Count; ++i) { tmpCollection.Add(childrenToPromote[i]); } } } } return tmpCollection; }