예제 #1
0
        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;
        }