InfoCardXmlSerializer.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 / InfoCardXmlSerializer.cs / 2 / InfoCardXmlSerializer.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.InfoCards
{ 
    using System;
    using System.Xml; 
    using System.Xml.Schema; 
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Cryptography.Xml; 
    using System.Collections.Generic;
    using System.Collections;
    using System.ServiceModel;
    using System.IO; 
    using System.Reflection;
    using System.Globalization; 
    using System.Security.Cryptography; 

    using Microsoft.InfoCards.Diagnostics; 
    using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace;
    using System.IdentityModel.Tokens;

 
    //
    // This class manages the deserialization of an infocard 
    // as an XML file as specified by WS-Identity 
    //
    internal class InfoCardXmlSerializer 
    {
        InfoCard m_card = null;
        X509Certificate2 m_issuer = null;
        X509Certificate2Collection m_additionalIssuerCerts = null; 
        bool m_isIssuerChainTrusted = false;
        bool m_checkSignature = false; 
        bool m_isDeserialized = false; 
        StoreConnection m_connection;
 
        public InfoCardXmlSerializer( StoreConnection connection )
        {
            m_connection = connection;
        } 

        public InfoCard Card 
        { 
            get
            { 
                if( m_isDeserialized )
                {
                    return m_card;
                } 
                else
                { 
                    return null; 
                }
            } 
        }

        public X509Certificate2 Issuer
        { 
            get
            { 
                if( m_isDeserialized ) 
                {
                    return m_issuer; 
                }
                else
                {
                    return null; 
                }
 
            } 

        } 

        public X509Certificate2Collection AdditionalIssuerCerts
        {
            get 
            {
                return m_additionalIssuerCerts; 
            } 
        }
 
        public bool IsIssuerChainTrusted
        {

            get 
            {
                // 
                // This function should only be called after deserialization 
                //
                IDT.Assert( m_isDeserialized, "Card should be deserialized before checking this value" ); 
                return m_isIssuerChainTrusted;
            }
        }
 

 
        public bool CheckSignature 
        {
            set { m_checkSignature = value; } 
        }


        // 
        // Summary
        //  Deserialize a managed infocard xml file 
        // 
        // Parameters
        //  filename - name of the managed card file 
        //
        //
        public void Deserialize( string filename )
        { 

            try 
            { 
                m_card = new InfoCard();
                m_card.HashSalt = InfoCard.GenerateSalt(); 
                CreateCardFromXml( filename );
                m_card.IssuerIdentifierAsBytes =
                    Convert.FromBase64String(
                        Recipient.CertGetRecipientOrganizationPPIDSeedHash( 
                        m_issuer, m_additionalIssuerCerts, m_isIssuerChainTrusted ) );
                m_isDeserialized = true; 
 
            }
            catch( Exception e ) 
            {
                if( IDT.IsFatal( e ) )
                {
                    throw; 
                }
                throw IDT.ThrowHelperError( 
                        new ImportException( SR.GetString( SR.InvalidImportFile ), e ) ); 

            } 


        }
 

        // 
        // Summary 
        //   Populate the infocard by parsing a managed card file
        // 
        // Parameter
        //   reader - The XmlReader to read from
        //
        private void CreateCardFromXml( string filename ) 
        {
            try 
            { 
                //
                // File.OpenRead( filename )is equivalent to 
                // FileStream(String, FileMode.Open, FileAccess.Read, FileShare.Read).
                // So the file is locked.
                //
                using( FileStream file = File.OpenRead( filename ) ) 
                {
                    // 
                    // Use a stream that validates the xml against internally stored schemas. 
                    //
                    XmlReaderSettings settings = new XmlReaderSettings(); 
                    settings.IgnoreWhitespace = false;
                    settings.IgnoreProcessingInstructions = false;
                    settings.IgnoreComments = true;
 
                    using( XmlReader reader = InfoCardSchemas.CreateReader( file, settings ) )
                    { 
                        RetrieveIssuerAndCheckSign( reader ); 

                        file.Seek( 0, SeekOrigin.Begin ); 

                        settings = InfoCardSchemas.CreateDefaultReaderSettings();
                        settings.IgnoreWhitespace = false;
                        using( XmlReader inner = InfoCardSchemas.CreateReader( file, settings ) ) 
                        {
                            while( inner.Read() ) 
                            { 
                                if( inner.LocalName == XmlNames.WSIdentity.InfoCardElement )
                                { 
                                    m_card.ReadXml( inner );
                                    break;
                                }
                            } 
                            //
                            // Make sure that there is only one card per file and we have reached the end signature element 
                            // 
                            inner.Read();
 
                            if( XmlNames.XmlDSig.Signature != inner.LocalName || XmlNodeType.EndElement != inner.NodeType )
                            {
                                throw IDT.ThrowHelperError(
                                    new ImportException( SR.GetString( SR.InvalidImportFile ) ) ); 
                            }
                        } 
                    } 

 
                }
            }
            catch( XmlSchemaValidationException e )
            { 
                throw IDT.ThrowHelperError(
                    new ImportException( SR.GetString( SR.InvalidImportFile ), e ) ); 
            } 
            catch( CryptographicException e )
            { 
                throw IDT.ThrowHelperError(
                    new ImportException( SR.GetString( SR.InvalidImportFile ), e ) );
            }
            catch( UnauthorizedAccessException e ) 
            {
                throw IDT.ThrowHelperError( 
                    new ImportException( SR.GetString( SR.ImportInaccesibleFile ), e ) ); 
            }
            catch( FileNotFoundException e ) 
            {
                throw IDT.ThrowHelperError(
                    new ImportException( SR.GetString( SR.ImportFileNotFound ), e ) );
            } 
            catch( IOException e )
            { 
                throw IDT.ThrowHelperError( 
                    new ImportException( SR.GetString( SR.InvalidImportFile ), e ) );
            } 
        }

        //
        // Summary 
        //  Retrive the issuer of the infocard. this function also checks the signature
        // 
        // Parameters 
        //   The filename to read data from
        // 
        private void RetrieveIssuerAndCheckSign( XmlReader reader )
        {

 
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.PreserveWhitespace = true; 
            xmlDocument.Load( reader ); 
            XmlNamespaceManager mgr = XmlNames.CreateNamespaceManager( xmlDocument.NameTable );
 
            if( XmlNames.XmlDSig.Signature != xmlDocument.DocumentElement.LocalName
                && XmlNames.XmlDSig.Namespace == xmlDocument.DocumentElement.NamespaceURI )
            {
                throw IDT.ThrowHelperError( new IdentityValidationException( 
                                     SR.GetString( SR.SignatureNotVerified ) ) );
            } 
 
            //
            // Check the signature 
            //
            SignedXml signedXml = new SignedXml( xmlDocument );

            signedXml.LoadXml( xmlDocument.DocumentElement ); 

            // 
            // check if appropriate transforms and algorithms are used 
            //
            if( null == signedXml.Signature || 
                null == signedXml.Signature.ObjectList ||
                null == signedXml.Signature.SignedInfo ||
                null == signedXml.Signature.SignedInfo.References ||
                null == ( (Reference)signedXml.Signature.SignedInfo.References[ 0 ] ).TransformChain ) 
            {
                throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.SignatureNotVerified ) ) ); 
            } 

            // 
            // verify there is a single object, a single reference and a single transform specified
            //
            if( signedXml.Signature.ObjectList.Count != 1 ||
                signedXml.Signature.SignedInfo.References.Count != 1 || 
                ( (Reference)signedXml.Signature.SignedInfo.References[ 0 ] ).TransformChain.Count != 1 )
            { 
                throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.SignatureNotVerified ) ) ); 
            }
 
            //
            // verify the algorithms
            //
 
            string transformAlg = ( (Reference)signedXml.Signature.SignedInfo.References[ 0 ] ).TransformChain[ 0 ].Algorithm;
 
            if( signedXml.Signature.SignedInfo.SignatureMethod != SignedXml.XmlDsigRSASHA1Url || 
                        ( SignedXml.XmlDsigExcC14NTransformUrl != transformAlg &&
                        SignedXml.XmlDsigExcC14NWithCommentsTransformUrl != transformAlg ) || 
                SignedXml.XmlDsigExcC14NTransformUrl != signedXml.Signature.SignedInfo.CanonicalizationMethodObject.Algorithm ||
                SignedXml.XmlDsigSHA1Url != ( (Reference)signedXml.Signature.SignedInfo.References[ 0 ] ).DigestMethod )
            {
                throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.SignatureNotVerified ) ) ); 
            }
 
 
            if( null == signedXml.KeyInfo )
            { 
                throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.SignatureNotVerified ) ) );
            }

 
            //
            // Retrieve the certificate from the signature 
            // We need to ensure that there is a valid X509Data element 
            //
            XmlNodeList nodeList = signedXml.KeyInfo.GetXml().ChildNodes; 
            KeyInfoX509Data data = new KeyInfoX509Data();

            //
            // Iterate through all the elements in Keyinfo to find X509Data 
            //
            foreach( XmlNode node in nodeList ) 
            { 
                if( XmlNames.XmlDSig.Namespace == node.NamespaceURI && XmlNames.XmlDSig.X509DataElement == node.Name )
                { 
                    data.LoadXml( (XmlElement)node );
                    break;
                }
            } 
            ArrayList list = data.Certificates;
            if( null != list && list.Count > 0 ) 
            { 
                m_issuer = (X509Certificate2)list[ 0 ];
                m_additionalIssuerCerts = new X509Certificate2Collection(); 
                for( int i = 1; i < list.Count; i++ )
                {
                    m_additionalIssuerCerts.Add( ( X509Certificate2 ) list[ i ] );
                } 
            }
            else 
            { 
                throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.NoCertificateFoundInSignature ) ) );
            } 


            //
            // Verify chain or peer trusted. Either machine or user roots are ok. 
            //
            try 
            { 
                InfoCardX509Validator.ValidateChainOrPeer( m_issuer, m_additionalIssuerCerts, out m_isIssuerChainTrusted );
            } 
            catch( SecurityTokenValidationException validationE )
            {
                throw IDT.ThrowHelperError(
                        new IdentityValidationException( validationE.Message ) ); 

            } 
 
            //
            // verify the signature 
            //
            if( m_checkSignature )
            {
                if( !signedXml.CheckSignature( m_issuer, true ) ) 
                {
                    throw IDT.ThrowHelperError( new IdentityValidationException( SR.GetString( SR.SignatureNotVerified ) ) ); 
                } 

            } 

        }

 

    } 
 
}
 


// 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