InfoCardPolicy.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / InfoCardPolicy.cs / 1 / InfoCardPolicy.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
//
// Presharp uses the c# pragma mechanism to supress its warnings. 
// These are not recognised by the base compiler so we need to explictly
// disable the following warnings. See http://winweb/cse/Tools/PREsharp/userguide/default.asp 
// for details. 
//
#pragma warning disable 1634, 1691      // unknown message, unknown pragma 



namespace Microsoft.InfoCards 
{
    using System; 
    using System.Collections.Generic; 
    using System.Diagnostics;
    using System.IO; //Stream 
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Cryptography.Xml;
    using System.IdentityModel.Tokens; 
    using System.IdentityModel.Selectors;
    using System.ServiceModel; 
    using System.ServiceModel.Channels; 
    using System.ServiceModel.Security;
    using System.ServiceModel.Security.Tokens; 
    using System.Text;
    using System.Xml;
    using System.Globalization;
    using System.Xml.Schema; 

    using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace; 
 

    // 
    // Summary
    // This is hopefully a temporary enum until Indigo's SecurityKeyType
    // supports NoProofKey.
    // 
    internal enum SecurityKeyTypeInternal
    { 
        SymmetricKey, 
        AsymmetricKey,
        NoKey 
    }

    internal enum PolicyUsageContext
    { 
        Browser,
        Intermediate, 
        GetToken 
    }
 
    //
    // Summary:
    // Given WS-Identity policy (from PS or STS) in the form of XML strings reads the policy and populates appropriate properties.
    // 
    internal class InfoCardPolicy
    { 
        static XmlNamespaceManager m_defNamespaces = XmlNames.CreateNamespaceManager( new NameTable() ); 

        EndpointAddress m_issuer;                   // Issuer of the security token as specified by the RP's security policy 
        string m_privacyPolicyLink = String.Empty;  // The link to RP's privacy policy
        uint m_privacyPolicyVersion;                // RP's privacy policy version
        bool m_isManaged;                           // Does the policy belong to a STS requiring a managed card.
        bool m_requiresManagedCard;                 // Determines if only managed card can satisfy policy. 

        RecipientIdentity m_immediateTokenRecipientIdentity; // The term "immediateTokenRecipient" refers to the STS/party we are encrypting the token to 
        RecipientIdentity m_recipientIdentity;               // The term "Recipient" refers to the relying party 

        Policy m_policyPrimary;                     // Policy that originated from the Client (developer settings + Indigo applied defaults). 
        Policy m_policySecondary;                   // Original policy that was specified by the Relying Party.

        //
        // A merged policy that exposes the appropriate values from both Primary and Secondary policy.  Whenever possible, 
        // the merged policy will take its values from the Primary policy.  If the value is missing, then it will retrieve it from
        // the Secondary policy.  See CreateMergedPolicy(). 
        // 
        Policy m_policyMerged;
 
        readonly PolicyUsageContext m_policyUsageContext;

        //
        // Helper constructor to gate constructor 
        //
        public InfoCardPolicy( 
                    EndpointAddress immediateTokenRecipient, 
                    EndpointAddress issuer,
                    ParsedPolicy policy, 
                    PolicyUsageContext policyUsageContext,
                    string privacyUrl,
                    uint privacyVersion,
                    RecipientIdentity recipientIdentity, 
                    bool isManaged )
        { 
 
            m_policyUsageContext = policyUsageContext;
            m_issuer = issuer; 
            m_recipientIdentity = recipientIdentity;

            m_immediateTokenRecipientIdentity = RecipientIdentity.CreateIdentity( immediateTokenRecipient, false );
 
            m_isManaged = isManaged;
 
            if( null != policy ) 
            {
                ParseIncomingPolicy( policy ); 
            }

            if( !IsSelfIssuedUriPresent( m_issuer ) )
            { 
                //
                // SelfIssuedUri absent --> either it is null/anonymous or it is a managed issuer 
                // 
                if( issuer != null && !Utility.CompareUri( issuer.Uri, new Uri( XmlNames.WSIdentity.AnonymousIssuerUri ) ) )
                { 
                    //If not null, then only a managed card can satisfy policy
                    m_requiresManagedCard = true;
                }
            } 

            m_privacyPolicyLink = privacyUrl; 
            m_privacyPolicyVersion = privacyVersion; 

        } 

        private void ParseIncomingPolicy( ParsedPolicy parsedPolicy )
        {
            // 
            // Check to see if we are receiving a single policy or a set of RP and Client policies.
            // 
            if( PolicyType.Composite == parsedPolicy.PolicyType ) 
            {
                try 
                {
                    m_policyPrimary = PolicyFactory.CreatePolicyFromUnwrappedPolicyXml( parsedPolicy.PolicyXmlPrimary );

                    m_policySecondary = PolicyFactory.CreatePolicyFromUnwrappedPolicyXml( parsedPolicy.PolicyXmlSecondary ); 

                    m_policyMerged = Policy.CreateMergedPolicy( parsedPolicy.PolicyXmlOriginal, m_policyPrimary, m_policySecondary ); 
                } 
                catch( XmlSchemaValidationException e )
                { 
                    throw IDT.ThrowHelperError( new PolicyValidationException( SR.GetString( SR.SchemaValidationFailed ), e ) );
                }
            }
            else if( PolicyType.PrimaryOnly == parsedPolicy.PolicyType ) 
            {
                try 
                { 
                    m_policyPrimary = PolicyFactory.CreatePolicyFromUnwrappedPolicyXml( parsedPolicy.PolicyXmlPrimary );
 
                    //
                    // Since we only have one policy in this case, make it the official "merged" policy.
                    //
                    m_policyMerged = m_policyPrimary; 
                }
                catch( XmlSchemaValidationException e ) 
                { 
                    throw IDT.ThrowHelperError( new PolicyValidationException( SR.GetString( SR.SchemaValidationFailed ), e ) );
                } 
            }
            else if( PolicyType.SecondaryOnly == parsedPolicy.PolicyType )
            {
                try 
                {
                    m_policySecondary = PolicyFactory.CreatePolicyFromUnwrappedPolicyXml( parsedPolicy.PolicyXmlSecondary ); 
 
                    //
                    // Since we only have one policy in this case, make it the official "merged" policy. 
                    //
                    m_policyMerged = m_policySecondary;
                }
                catch( XmlSchemaValidationException e ) 
                {
                    throw IDT.ThrowHelperError( new PolicyValidationException( SR.GetString( SR.SchemaValidationFailed ), e ) ); 
                } 
            }
            else 
            {
                //
                // We are ensured that this case will not happen since ParsedPolicy will throw if it gets a null/empty for both primary
                // and secondary policy. 
                //
            } 
        } 

        public Policy MergedPolicy 
        {
            get { return m_policyMerged; }
        }
 
        public string RequestType
        { 
            get { return m_policyMerged.RequestType; } 
        }
 
        public Policy ClientPolicy
        {
            get { return m_policyPrimary; }
        } 

        public Policy RelyingPartyPolicy 
        { 
            get { return m_policySecondary; }
        } 

        public OptionalRstParameters OptionalRstParams
        {
            get { return m_policyMerged.OptionalRstParams; } 
        }
 
        public string[] RequiredClaims 
        {
            get { return m_policyMerged.RequiredClaims; } 
        }

        public string[] OptionalClaims
        { 
            get { return m_policyMerged.OptionalClaims; }
        } 
 
        public SecurityKeyTypeInternal KeyType
        { 
            get
            {
                return m_policyMerged.KeyType;
            } 
        }
 
        public bool KeyTypeSpecified 
        {
            get 
            {
                return m_policyMerged.KeyTypeSpecified;
            }
        } 

 
        public EndpointAddress PolicyAppliesTo 
        {
            get 
            {
                return m_policyMerged.PolicyAppliesTo;
            }
        } 

        public MemoryStream UnprocessedPolicyElements 
        { 
            get { return m_policyMerged.UnprocessedPolicyElements; }
        } 

        public bool KeySizeSpecified
        {
            get 
            {
                return m_policyMerged.KeySizeSpecified; 
            } 
        }
 
        public uint KeySize
        {
            get { return m_policyMerged.KeySize; }   /* SSS_WARNINGS_OFF */
        } 

       public bool NonWhiteListElementsFound 
        { 
            get { return m_policyMerged.NonWhiteListElementsFound; }
        } 

        public List NonWhiteListElements
        {
            get { return m_policyMerged.NonWhiteListElements; } 
        }              					/* SSS_WARNINGS_ON */
 
        public ProtocolProfile ProtocolVersionProfile 
        {
            get 
            {
                return m_policyMerged.ProtocolVersionProfile;
            }
        } 

        public RecipientIdentity ImmediateTokenRecipient 
        { 
            get
            { 
                return m_immediateTokenRecipientIdentity;
            }
        }
 
        public EndpointAddress Issuer
        { 
            get { return m_issuer; } 
        }
 
        public RecipientIdentity Recipient
        {
            get { return m_recipientIdentity; }
        } 

        public UInt32 GetIntelligentKeySize(bool isSelfIssuedCardSelected) 
        { 
            if( isSelfIssuedCardSelected )
            { 
                throw IDT.ThrowHelperError( new InvalidOperationException() );
            }
            else
            { 
                //
                // Managed card case - sending RST to IP/STS 
                // 
                if( SecurityKeyTypeInternal.AsymmetricKey == KeyType )
                { 
                    //
                    // We only support 2048 in useKey currently, so override what's in policy
                    //
                    return InfoCard.KeySize; 
                }
                else if( SecurityKeyTypeInternal.SymmetricKey == KeyType ) 
                { 
                    if( !KeySizeSpecified )
                    { 
                        return (UInt32)SecurityAlgorithmSuite.Default.DefaultSymmetricKeyLength;
                    }
                    else
                    { 
                        return KeySize;
                    } 
                } 
                else
                { 
                    IDT.Assert( false, "Should access this property only in managed card non-no proof key scenario" );
                    throw IDT.ThrowHelperError( new InvalidOperationException() );
                }
            } 
        }
 
        public string GetKeyTypeString() 
        {
            switch( KeyType ) 
            {
                case SecurityKeyTypeInternal.AsymmetricKey:
                    return m_policyMerged.ProtocolVersionProfile.WSTrust.KeyTypeAsymmetric.ToString();
 
                case SecurityKeyTypeInternal.SymmetricKey:
                    return m_policyMerged.ProtocolVersionProfile.WSTrust.KeyTypeSymmetric.ToString(); 
 
                case SecurityKeyTypeInternal.NoKey:
                    return m_policyMerged.ProtocolVersionProfile.WSTrust.KeyTypeBearer.ToString(); 

                default:
                    IDT.Assert( false, "Impossible condition in code" );
                    throw IDT.ThrowHelperError( new InvalidOperationException() ); 

            } 
 
        }
 
        public string PrivacyPolicyLink
        {
            get { return m_privacyPolicyLink; }
        } 

        public uint PrivacyPolicyVersion 
        { 
            get { return m_privacyPolicyVersion; }
        } 

        public bool IsManaged
        {
            get { return m_isManaged; } 
        }
 
        public bool RequiresManagedCard 
        {
            get 
            {
                return m_requiresManagedCard;
            }
        } 

        public bool RequiresSelfIssuedCard 
        { 
            get
            { 
                if( null == m_issuer )
                {
                    return false;
                } 
                return Utility.CompareUri( m_issuer.Uri, new Uri( XmlNames.WSIdentity.SelfIssuerUri ) );
            } 
        } 

        // 
        // Summary:
        // Set the recipient info (the party we show in the RIP page) so that it can be be validated and used
        //
        // Arguments: 
        // recipientIdentity - the identity information for the final recipient
        // privacyUrl - the privacy URL for the recipient 
        // privacyVersion - the privacy version 
        //
        public void SetRecipientInfo( 
                RecipientIdentity recipientIdentity,
                string privacyUrl,
                uint privacyVersion)
        { 
            m_recipientIdentity = recipientIdentity;
            m_privacyPolicyLink = privacyUrl; 
            m_privacyPolicyVersion = privacyVersion; 
        }
 

        //
        // Summary:
        // Computes the IsManaged flag based on recieved policy.  If the flag is already set to true this method 
        // will not reset it.
        // 
        private void ComputeRequiresManagedCardFlag()		/* SSS_WARNINGS_OFF */ 
        {
            if( m_policyMerged.NonWhiteListElementsFound ) 
            {
                m_requiresManagedCard = true;
            }							/* SSS_WARNINGS_ON */
 
            foreach( string clm in m_policyMerged.RequiredClaims )
            { 
                if( !PolicyUtility.IsSelfIssuedClaim( clm ) ) 
                {
                    m_requiresManagedCard = true; 
                }
            }

            // 
            // Check token type. Only saml tokens are supported for v1.
            // 
            if( !String.IsNullOrEmpty( m_policyMerged.OptionalRstParams.TokenType ) 
               && !PolicyUtility.IsSelfIssuedTokenType( m_policyMerged.OptionalRstParams.TokenType ) )
            { 
                m_requiresManagedCard = true;
            }

            // 
            // Check is the keytype is correct
            // 
            if( !( m_immediateTokenRecipientIdentity is X509RecipientIdentity ) 
                && SecurityKeyTypeInternal.SymmetricKey == m_policyMerged.KeyType )
            { 
                m_requiresManagedCard = true;
            }

            // 
            // Check the KeyWrapAlgorithm.  The local token factory only supports the default algorithm.
            // 
            if( ( !String.IsNullOrEmpty( m_policyMerged.OptionalRstParams.KeyWrapAlgorithm ) ) && 
                ( m_policyMerged.OptionalRstParams.KeyWrapAlgorithm != SecurityAlgorithmSuite.Default.DefaultAsymmetricKeyWrapAlgorithm ) )
            { 
                m_requiresManagedCard = true;
            }
        }
 
        private void FillComputedPolicy()
        { 
            ComputeRequiresManagedCardFlag(); 
        }
 
        public void Validate()
        {
            //
            // Check requested claims 
            //
            bool noRequiredClaimsInPolicy = ( null == m_policyMerged.RequiredClaims || 0 == m_policyMerged.RequiredClaims.Length ); 
 
            PolicyValidator validator = null;
 
            if( PolicyUsageContext.Browser == m_policyUsageContext )
            {
                if( noRequiredClaimsInPolicy )
                { 
                    throw IDT.ThrowHelperError( new PolicyValidationException( SR.GetString( SR.NoClaimsFoundInPolicy ) ) );
                } 
 
                FillComputedPolicy();
 
                validator = new BrowserPolicyValidator( this );
            }
            else if( PolicyUsageContext.GetToken == m_policyUsageContext )
            { 
                if( noRequiredClaimsInPolicy )
                { 
                    throw IDT.ThrowHelperError( new PolicyValidationException( SR.GetString( SR.NoClaimsFoundInPolicy ) ) ); 
                }
 
                FillComputedPolicy();

                validator = new PolicyValidator( this );
            } 
            else
            { 
                // 
                // Intermediate policy does not need to calculate computed policy elements
                // 
                validator = new IntermediatePolicyValidator( this );
            }

            validator.Validate(); 
        }
 
        // 
        // Summary:
        // If the IP/STS (using self-issued card for authentication)asks anything else but the PPID claim 
        // we will throw a PolicyValidationException
        //
        public void ThrowIfNonPpidClaimsPresent()
        { 
            IDT.ThrowInvalidArgumentConditional( m_policyMerged.RequiredClaims == null
                                                || m_policyMerged.OptionalClaims == null 
                                                , "claims" ); 

            if( m_policyMerged.RequiredClaims.Length == 1 && 
                m_policyMerged.RequiredClaims[ 0 ] == InfoCardConstants.PPIDClaimsUri &&
                m_policyMerged.OptionalClaims.Length == 0 )
            {
                // 
                // We're OK
                // 
                ; 
            }
            else 
            {
                throw IDT.ThrowHelperError(
                    new PolicyValidationException(
                        SR.GetString( SR.IPStsPolicyRequestingNonPpidClaims ) ) ); 
            }
        } 
 
        //
        // Utility functions 
        //

        public static bool IsSelfIssuedUriPresent( EndpointAddress address )
        { 
            if( null == address )
            { 
                // 
                // Policy is stating null issuer, so self issued URI not present
                // 
                return false;
            }

            if( Utility.CompareUri( address.Uri, XmlNames.WSIdentity.SelfIssuerUriValue ) ) 
            {
                return true; 
            } 
            return false;
        } 
    }
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK