InfoCardMasterKey.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 / InfoCardMasterKey.cs / 1 / InfoCardMasterKey.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.InfoCards
{ 
    using System;
    using System.IO; 
    using System.Text; 
    using System.Collections;
    using System.Collections.Generic; 
    using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace;
    using System.Security.Cryptography;

 
    //
    // Summary: 
    // Class to encapsulate the infocard masterkey. 
    // Other classes use the InfoCard object to interact with this class.
    // 
    internal class InfoCardMasterKey
    {
        //
        // Random value used to mark the start/end of serialized object. 
        //
        const byte Marker = 29; 
 
        //
        // Used to verify the serialized version of the InfoCardMasterKey 
        //
        const byte Version = 1;

        Uri                 m_infoCardId; 
        byte[ ]             m_key;
 
        // 
        // Summary: Constructor
        // 
        // Usage Remarks:
        // Used this constructor to create a masterkey
        // object that will be used to access an existing masterkey in the store
        // 
        public InfoCardMasterKey( Uri infoCardId )
        { 
            m_infoCardId = infoCardId; 
        }
 
        //
        // Summary: Constructor
        //
        // Usage Remarks: 
        // Used this constructor to create a masterkey for a known key
        // 
        public InfoCardMasterKey( Uri infoCardId, byte[] key ) 
        {
            m_infoCardId = infoCardId; 
            m_key = key;
        }

        // 
        // Summary: Creates a new masterkey object that is populated using
        // GenerateKey(). 
        // 
        // Arguments:
        //   infoCardId - the id of the infocard we want to create the masterkey for 
        //
        public static InfoCardMasterKey NewMasterKey( Uri infoCardId )
        {
            InfoCardMasterKey imk = new InfoCardMasterKey( infoCardId ); 
            IDT.Assert( null == imk.m_key, "Should be null" );
            imk.m_key = GenerateKey(); 
            return imk; 
        }
 
        public byte[] Key
        {
            get{ return m_key; }
        } 

        // 
        // Summary 
        //   Generate a master key for the Infocard.
        // 
        // Returns
        //   The generated master key
        //
        private static byte [] GenerateKey () 
        {
            byte [] key = new byte [ InfoCard.MasterKeySize ]; 
            RNGCryptoServiceProvider prov = new RNGCryptoServiceProvider(); 
            prov.GetBytes( key );
            return key; 
        }

        //
        // Summary 
        // Retrieves an InfoCardMasterkey object from the store using the specified connection.
        // 
        // Remarks 
        // The m_infoCardId must be populated for this call to work.
        // The InfoCardMasterKey will be retrieved from the roaming portion of the store. 
        //
        // Parameters
        // con - The connection to the InfoCard store to be used for the query.
        // 
        public void Get( StoreConnection con )
        { 
            IDT.Assert( null != m_infoCardId ,"populate infocard id before calling Get" ); 
            IDT.Assert( con != null, "null connection" );
 

            //
            // Retrieve the row for the object from the database
            // 
            DataRow row = GetRow( con, QueryDetails.FullRow );
 
            // 
            // Populate the infocard using the byte array
            // 
            Deserialize( new MemoryStream( row.GetDataField() ) );
        }

        // 
        // Summary
        // Updates or inserts the InfoCardMasterkey instance into the roaming portion of the store using 
        // the specified connection. 
        //
        // Remarks 
        // The object must be complete for this operation to succeed.
        //
        // Parameters
        // con - The connection to the InfoCard store to be used for the query. 
        //
        public void Save( StoreConnection con ) 
        { 

            IDT.Assert( con != null, "null connection" ); 

            ThrowIfNotComplete();

            IDT.TraceDebug( "Service: Saving masterkey..." ); 

            // 
            // Try and get the database header information to 
            // see if this is an insert or update.
            // 
            // Note: The datafield is not part of the projection
            // in order to avoid unecessary decryption.
            //
            DataRow row = TryGetRow( con, QueryDetails.FullHeader ); 

            if ( null == row ) 
            { 
                row = new DataRow();
                row.ObjectType = ( Int32 ) StorableObjectType.InfoCardMasterkey; 
                row.GlobalId = Guid.NewGuid();
            }

 
            //
            // Populate the index fields 
            // 
            row.SetIndexValue(
                SecondaryIndexDefinition.ParentIdIndex, 
                GlobalId.DeriveFrom( m_infoCardId.ToString() ) );
            row.SetIndexValue( SecondaryIndexDefinition.MasterKeyIndex, m_key );

            // 
            // Populate the data object
            // 
            MemoryStream ms = new MemoryStream(); 
            Serialize( ms );
            row.SetDataField( ms.ToArray() ); 

            //
            // Save the row to the database
            // 
            con.Save( row );
 
        } 

        // 
        // Summary
        // Provides an indication of whether the required members of the this class
        // all properly specified.
        // 
        // Remarks
        // This function is useful to determine if the object is ready to be persisted. 
        // If an object is not complete or contains nulls for certain values the serialization 
        // code will not work.
        // 
        public void ThrowIfNotComplete()
        {
            bool isComplete = (
                null != m_infoCardId && 
                !Utility.ArrayIsNullOrEmpty( m_key ) );
 
            if ( !isComplete ) 
            {
                throw IDT.ThrowHelperError( new SerializationIncompleteException( this.GetType() ) ); 
            }
        }

        // 
        // Summary
        // Encrypt the master key using the key generated from the pin value. 
        // 
        // Parameters
        // pinHelper - A helper used to hold the key and related info. 
        //
        public void Encrypt( PinProtectionHelper pinHelper )
        {
            m_key = pinHelper.EncryptMasterKey( m_key ); 
        }
 
        // 
        // Summary
        // Decrypt the master key using the key generated from the pin value. 
        //
        //
        // Parameters
        // pinHelper - A helper used to hold the key and related info. 
        //
        public void Decrypt( PinProtectionHelper pinHelper ) 
        { 
            m_key = pinHelper.DecryptMasterKey( m_key );
        } 

        //
        // Summary
        // Retrieves the PKCS5 key generation data from the serialized 
        // bytes at the beginning of the master key field using
        // the specified pin 
        // 
        // Parameters
        // pin - Pin used to seed the PKCS5 algorithm. 
        //
        // Remarks
        // See the PinProtectionHelper class for a description of
        // the layout of the key information bytes. 
        //
        public PinProtectionHelper GetPinHelper( string pin ) 
        { 
            return new PinProtectionHelper( pin, m_key );
        } 

        //
        // Summary
        // Write binary sequence of instance members to the provided stream. 
        //
        // Parameters 
        // stream - binary stream conforming to the serialization format supported by this class. 
        //
        private void Serialize( System.IO.Stream stream ) 
        {
            ThrowIfNotComplete();

            // 
            // Setup a BinaryWriter to serialize the bytes of each member to the provided stream
            // 
            BinaryWriter writer = new BinaryWriter( stream, Encoding.Unicode ); 
            writer.Write( Version );
            Utility.SerializeBytes( writer, m_key ); 
            writer.Write( Marker );
        }

        // 
        // Summary
        // Populates the instance members from a binary stream of serialized data. 
        // 
        // Parameters
        // stream - binary stream conforming to the serialization format supported by this class. 
        //
        private void Deserialize( System.IO.Stream stream )
        {
            // 
            // Populate each member from the stream
            // 
            BinaryReader reader = new InfoCardBinaryReader( stream, Encoding.Unicode ); 
            //
            // Check the version 
            //

            if( Version != reader.ReadByte() )
            { 
               IDT.Assert( false, "Master key version mismatch" );
            } 
 
            m_key = reader.ReadBytes( reader.ReadInt32() );
 
            //
            // Validate the end of the buffer
            //
            if( Marker != reader.ReadByte() ) 
            {
                IDT.Assert( false, "Invalid stream detected" ); 
            } 

            // 
            // Just a correctness check
            //
            ThrowIfNotComplete();
        } 

        // 
        // Summary 
        // Attempts to retrieve the specified row information from the store
        // using the specified connection. 
        //
        // Remarks
        // The m_id field must be populated for this method to succeed.
        // 
        // Parameters
        // con      - The connection to the InfoCard store to be used for the query. 
        // details  - Identifies the projection (think columns) of data to be returned. 
        //            Since the data field must be decrypted before returning avoid projecting it if possible.
        // 
        // Returns
        // Will always return a row. If a row is not found an exception will be thrown.
        //
        protected DataRow GetRow( StoreConnection con, QueryDetails details ) 
        {
            DataRow row = TryGetRow( con, details ); 
 
            //
            // Verify that an infocardmasterkey row was returned 
            //

            IDT.Assert( null != row && ( Int32 ) StorableObjectType.InfoCardMasterkey == row.ObjectType ,
                        "invalid service object type" ); 
            return row;
        } 
 

        // 
        // Summary
        // Attempts to retrieve the specified row information from the store
        // using the specified connection.
        // 
        // Remarks
        // The m_infoCardId field must be populated for this method to succeed. 
        // Called by GetRow() 
        //
        // Parameters 
        // con      - The connection to the InfoCard store to be used for the query.
        // details  - Identifies the projection (think columns) of data to be returned.
        //            Since the data field must be decrypted before returning avoid projecting it if possible.
        // 
        // Returns
        // Will return null if the row associated with the m_id is not found. 
        // 
        protected DataRow TryGetRow( StoreConnection con, QueryDetails details )
        { 
            IDT.Assert( null != m_infoCardId, "populate cardid before retrieving row" );

            //
            // Retrieve a single object from the database. 
            //
            DataRow row = con.GetSingleRow( 
                                    details, 
                                    new QueryParameter( SecondaryIndexDefinition.ObjectTypeIndex,
                                    ( Int32 ) StorableObjectType.InfoCardMasterkey ), 
                                    new QueryParameter( SecondaryIndexDefinition.ParentIdIndex,
                                                        GlobalId.DeriveFrom( m_infoCardId.ToString() ) ) );

            return row; 
        }
    } 
} 

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