CapiHashAlgorithm.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Security / Cryptography / CapiHashAlgorithm.cs / 1305376 / CapiHashAlgorithm.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 

using System; 
using System.Diagnostics; 
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; 
using System.Diagnostics.Contracts;
using Microsoft.Win32.SafeHandles;

namespace System.Security.Cryptography { 
    /// 
    ///     Implementation of a generic CAPI hashing algorithm, concrete HashAlgorithm classes 
    ///     implemented by CAPI can contain an instance of this class and delegate the work to it 
    /// 
    internal sealed class CapiHashAlgorithm : IDisposable { 
        private CapiNative.AlgorithmId m_algorithmId;
        private SafeCspHandle m_cspHandle;
        private SafeCapiHashHandle m_hashHandle;
 
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        // 
        [System.Security.SecurityCritical] 
        public CapiHashAlgorithm(string provider,
                                 CapiNative.ProviderType providerType, 
                                 CapiNative.AlgorithmId algorithm) { 
            Contract.Requires(!String.IsNullOrEmpty(provider));
            Contract.Requires((CapiNative.AlgorithmClass)((uint)algorithm & (uint)CapiNative.AlgorithmClass.Hash) == CapiNative.AlgorithmClass.Hash); 
            Contract.Ensures(m_cspHandle != null && !m_cspHandle.IsInvalid && !m_cspHandle.IsClosed);
            Contract.Ensures(m_hashHandle != null && !m_hashHandle.IsInvalid && !m_hashHandle.IsClosed);

            m_algorithmId = algorithm; 
            m_cspHandle = CapiNative.AcquireCsp(null,
                                                provider, 
                                                providerType, 
                                                CapiNative.CryptAcquireContextFlags.VerifyContext,
                                                true); 
            Initialize();
        }

        //  
        // 
        //  
        //  
        // 
        //  
        [System.Security.SecurityCritical]
        public void Dispose() {
            Contract.Ensures(m_hashHandle == null || m_hashHandle.IsClosed);
            Contract.Ensures(m_cspHandle == null || m_cspHandle.IsClosed); 

            if (m_hashHandle != null) { 
                m_hashHandle.Dispose(); 
            }
 
            if (m_cspHandle != null) {
                m_cspHandle.Dispose();
            }
        } 

        ///  
        ///     Reset the hash algorithm to begin hashing a new set of data 
        /// 
        //  
        // 
        // 
        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        [System.Security.SecurityCritical]
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")]
        public void Initialize() { 
            Contract.Ensures(m_hashHandle != null && !m_hashHandle.IsInvalid && !m_hashHandle.IsClosed);
            Contract.Assert(m_cspHandle != null); 
 
            // Try to create a new hash algorithm to use
            SafeCapiHashHandle newHashAlgorithm = null; 
            if (!CapiNative.UnsafeNativeMethods.CryptCreateHash(m_cspHandle,
                                                                m_algorithmId,
                                                                SafeCapiKeyHandle.InvalidHandle,
                                                                0, 
                                                                out newHashAlgorithm)) {
                // BadAlgorithmId means that this CSP does not support the specified algorithm, which means 
                // that we're on a platform that does not support the given hash function. 
                int error = Marshal.GetLastWin32Error();
                if (error == (int)CapiNative.ErrorCode.BadAlgorithmId) { 
                    throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported));
                }
                else {
                    throw new CryptographicException(error); 
                }
            } 
 
            // If we created a new algorithm, dispose of the old one and use the new one
            Debug.Assert(newHashAlgorithm != null, "newHashAlgorithm != null"); 
            if (m_hashHandle != null) {
                m_hashHandle.Dispose();
            }
            m_hashHandle = newHashAlgorithm; 
        }
 
        ///  
        ///     Hash a block of data
        ///  
        // 
        // 
        // 
        //  
        // 
        [System.Security.SecurityCritical] 
        public void HashCore(byte[] array, int ibStart, int cbSize) { 
            Contract.Assert(m_hashHandle != null);
 
            if (array == null) {
                throw new ArgumentNullException("array");
            }
            if (ibStart < 0 || ibStart > array.Length - cbSize) { 
                throw new ArgumentOutOfRangeException("ibStart");
            } 
            if (cbSize < 0 || cbSize > array.Length) { 
                throw new ArgumentOutOfRangeException("cbSize");
            } 

            byte[] hashData = new byte[cbSize];
            Buffer.BlockCopy(array, ibStart, hashData, 0, cbSize);
 
            if (!CapiNative.UnsafeNativeMethods.CryptHashData(m_hashHandle, hashData, cbSize, 0)) {
                throw new CryptographicException(Marshal.GetLastWin32Error()); 
            } 
        }
 
        /// 
        ///     Complete the hash, returning its value
        /// 
        //  
        // 
        //  
        //  
        [System.Security.SecurityCritical]
        public byte[] HashFinal() { 
            Contract.Ensures(Contract.Result() != null);
            Contract.Assert(m_hashHandle != null);

            return CapiNative.GetHashParameter(m_hashHandle, CapiNative.HashParameter.HashValue); 
        }
    } 
} 

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

using System; 
using System.Diagnostics; 
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; 
using System.Diagnostics.Contracts;
using Microsoft.Win32.SafeHandles;

namespace System.Security.Cryptography { 
    /// 
    ///     Implementation of a generic CAPI hashing algorithm, concrete HashAlgorithm classes 
    ///     implemented by CAPI can contain an instance of this class and delegate the work to it 
    /// 
    internal sealed class CapiHashAlgorithm : IDisposable { 
        private CapiNative.AlgorithmId m_algorithmId;
        private SafeCspHandle m_cspHandle;
        private SafeCapiHashHandle m_hashHandle;
 
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        // 
        [System.Security.SecurityCritical] 
        public CapiHashAlgorithm(string provider,
                                 CapiNative.ProviderType providerType, 
                                 CapiNative.AlgorithmId algorithm) { 
            Contract.Requires(!String.IsNullOrEmpty(provider));
            Contract.Requires((CapiNative.AlgorithmClass)((uint)algorithm & (uint)CapiNative.AlgorithmClass.Hash) == CapiNative.AlgorithmClass.Hash); 
            Contract.Ensures(m_cspHandle != null && !m_cspHandle.IsInvalid && !m_cspHandle.IsClosed);
            Contract.Ensures(m_hashHandle != null && !m_hashHandle.IsInvalid && !m_hashHandle.IsClosed);

            m_algorithmId = algorithm; 
            m_cspHandle = CapiNative.AcquireCsp(null,
                                                provider, 
                                                providerType, 
                                                CapiNative.CryptAcquireContextFlags.VerifyContext,
                                                true); 
            Initialize();
        }

        //  
        // 
        //  
        //  
        // 
        //  
        [System.Security.SecurityCritical]
        public void Dispose() {
            Contract.Ensures(m_hashHandle == null || m_hashHandle.IsClosed);
            Contract.Ensures(m_cspHandle == null || m_cspHandle.IsClosed); 

            if (m_hashHandle != null) { 
                m_hashHandle.Dispose(); 
            }
 
            if (m_cspHandle != null) {
                m_cspHandle.Dispose();
            }
        } 

        ///  
        ///     Reset the hash algorithm to begin hashing a new set of data 
        /// 
        //  
        // 
        // 
        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        [System.Security.SecurityCritical]
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")]
        public void Initialize() { 
            Contract.Ensures(m_hashHandle != null && !m_hashHandle.IsInvalid && !m_hashHandle.IsClosed);
            Contract.Assert(m_cspHandle != null); 
 
            // Try to create a new hash algorithm to use
            SafeCapiHashHandle newHashAlgorithm = null; 
            if (!CapiNative.UnsafeNativeMethods.CryptCreateHash(m_cspHandle,
                                                                m_algorithmId,
                                                                SafeCapiKeyHandle.InvalidHandle,
                                                                0, 
                                                                out newHashAlgorithm)) {
                // BadAlgorithmId means that this CSP does not support the specified algorithm, which means 
                // that we're on a platform that does not support the given hash function. 
                int error = Marshal.GetLastWin32Error();
                if (error == (int)CapiNative.ErrorCode.BadAlgorithmId) { 
                    throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported));
                }
                else {
                    throw new CryptographicException(error); 
                }
            } 
 
            // If we created a new algorithm, dispose of the old one and use the new one
            Debug.Assert(newHashAlgorithm != null, "newHashAlgorithm != null"); 
            if (m_hashHandle != null) {
                m_hashHandle.Dispose();
            }
            m_hashHandle = newHashAlgorithm; 
        }
 
        ///  
        ///     Hash a block of data
        ///  
        // 
        // 
        // 
        //  
        // 
        [System.Security.SecurityCritical] 
        public void HashCore(byte[] array, int ibStart, int cbSize) { 
            Contract.Assert(m_hashHandle != null);
 
            if (array == null) {
                throw new ArgumentNullException("array");
            }
            if (ibStart < 0 || ibStart > array.Length - cbSize) { 
                throw new ArgumentOutOfRangeException("ibStart");
            } 
            if (cbSize < 0 || cbSize > array.Length) { 
                throw new ArgumentOutOfRangeException("cbSize");
            } 

            byte[] hashData = new byte[cbSize];
            Buffer.BlockCopy(array, ibStart, hashData, 0, cbSize);
 
            if (!CapiNative.UnsafeNativeMethods.CryptHashData(m_hashHandle, hashData, cbSize, 0)) {
                throw new CryptographicException(Marshal.GetLastWin32Error()); 
            } 
        }
 
        /// 
        ///     Complete the hash, returning its value
        /// 
        //  
        // 
        //  
        //  
        [System.Security.SecurityCritical]
        public byte[] HashFinal() { 
            Contract.Ensures(Contract.Result() != null);
            Contract.Assert(m_hashHandle != null);

            return CapiNative.GetHashParameter(m_hashHandle, CapiNative.HashParameter.HashValue); 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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