CapiSafeHandles.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 / Microsoft / Win32 / SafeHandles / CapiSafeHandles.cs / 1305376 / CapiSafeHandles.cs

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

using System; 
using System.Diagnostics; 
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution; 
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Diagnostics.CodeAnalysis; 
using System.Diagnostics.Contracts;
 
namespace Microsoft.Win32.SafeHandles { 
    /// 
    ///     SafeHandle for buffers returned by the Axl APIs 
    /// 
    // 
    // 
    //  
#pragma warning disable 618    // Have not migrated to v4 transparency yet
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)] 
#pragma warning restore 618 
    internal sealed class SafeAxlBufferHandle : SafeHandleZeroOrMinusOneIsInvalid {
        private SafeAxlBufferHandle() : base(true) { 
            return;
        }

        [DllImport("kernel32")] 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity] 
        private static extern IntPtr GetProcessHeap(); 

        [DllImport("kernel32")] 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool HeapFree(IntPtr hHeap, int dwFlags, IntPtr lpMem); 

        protected override bool ReleaseHandle() { 
            // _AxlFree is a wrapper around HeapFree on the process heap. Since it is not exported from mscorwks 
            // we just call HeapFree directly. This needs to be updated if _AxlFree is ever changed.
            HeapFree(GetProcessHeap(), 0, handle); 
            return true;
        }
    }
 
    /// 
    ///     SafeHandle for CAPI hash algorithms (HCRYPTHASH) 
    ///  
    // 
    //  
    // 
#pragma warning disable 618    // Have not migrated to v4 transparency yet
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618 
    internal sealed class SafeCapiHashHandle : SafeHandleZeroOrMinusOneIsInvalid {
        private SafeCapiHashHandle() : base(true) { 
        } 

        ///  
        ///     NULL hash handle
        /// 
        public static SafeCapiHashHandle InvalidHandle {
            get { 
                SafeCapiHashHandle handle = new SafeCapiHashHandle();
                handle.SetHandle(IntPtr.Zero); 
                return handle; 
            }
        } 

        [DllImport("advapi32")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity] 
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptDestroyHash(IntPtr hHash); 
 
        protected override bool ReleaseHandle() {
            return CryptDestroyHash(handle); 
        }
    }

    ///  
    ///     SafeHandle for CAPI keys (HCRYPTKEY)
    ///  
    //  
    // 
    //  
#pragma warning disable 618    // Have not migrated to v4 transparency yet
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618
    internal sealed class SafeCapiKeyHandle : SafeHandleZeroOrMinusOneIsInvalid { 
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        private SafeCapiKeyHandle() : base(true) { 
        } 

        ///  
        ///     NULL key handle
        /// 
        internal static SafeCapiKeyHandle InvalidHandle {
            [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
            get {
                SafeCapiKeyHandle handle = new SafeCapiKeyHandle(); 
                handle.SetHandle(IntPtr.Zero); 
                return handle;
            } 
        }

        [DllImport("advapi32")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)] 
        private static extern bool CryptDestroyKey(IntPtr hKey); 

        ///  
        ///     Make a copy of this key handle
        /// 
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        internal SafeCapiKeyHandle Duplicate() { 
            Contract.Requires(!IsInvalid && !IsClosed);
            Contract.Ensures(Contract.Result() != null && !Contract.Result().IsInvalid && !Contract.Result().IsClosed); 
 
            SafeCapiKeyHandle duplicate = null;
            if (!CapiNative.UnsafeNativeMethods.CryptDuplicateKey(this, IntPtr.Zero, 0, out duplicate)) { 
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            return duplicate; 
        }
 
        protected override bool ReleaseHandle() { 
            return CryptDestroyKey(handle);
        } 
    }

    /// 
    ///     SafeHandle for crypto service providers (HCRYPTPROV) 
    /// 
    //  
    //  
    // 
#pragma warning disable 618    // Have not migrated to v4 transparency yet 
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618
    internal sealed class SafeCspHandle : SafeHandleZeroOrMinusOneIsInvalid {
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        private SafeCspHandle() : base(true) {
            return; 
        } 

        [DllImport("advapi32", SetLastError = true)] 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptContextAddRef(SafeCspHandle hProv, 
                                                     IntPtr pdwReserved,
                                                     int dwFlags); 
 
        [DllImport("advapi32")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptReleaseContext(IntPtr hProv, int dwFlags);
 
        /// 
        ///     Create a second SafeCspHandle which refers to the same HCRYPTPROV 
        ///  
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        public SafeCspHandle Duplicate() { 
            Contract.Requires(!IsInvalid && !IsClosed);

            // In the window between the call to CryptContextAddRef and when the raw handle value is assigned
            // into this safe handle, there's a second reference to the original safe handle that the CLR does 
            // not know about, so we need to bump the reference count around this entire operation to ensure
            // that we don't have the original handle closed underneath us. 
            bool acquired = false; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                DangerousAddRef(ref acquired);
                IntPtr originalHandle = DangerousGetHandle();

                int error = (int)CapiNative.ErrorCode.Success; 

                SafeCspHandle duplicate = new SafeCspHandle(); 
 
                // A successful call to CryptContextAddRef and an assignment of the handle value to the duplicate
                // SafeHandle need to happen atomically, so we contain them within a CER. 
                RuntimeHelpers.PrepareConstrainedRegions();
                try { }
                finally {
                    if (!CryptContextAddRef(this, IntPtr.Zero, 0)) { 
                        error = Marshal.GetLastWin32Error();
                    } 
                    else { 
                        duplicate.SetHandle(originalHandle);
                    } 
                }

                // If we could not call CryptContextAddRef succesfully, then throw the error here otherwise
                // we should be in a valid state at this point. 
                if (error != (int)CapiNative.ErrorCode.Success) {
                    duplicate.Dispose(); 
                    throw new CryptographicException(error); 
                }
                else { 
                    Debug.Assert(!duplicate.IsInvalid, "Failed to duplicate handle successfully");
                }

                return duplicate; 
            }
            finally { 
                if (acquired) { 
                    DangerousRelease();
                } 
            }
        }

        protected override bool ReleaseHandle() { 
            return CryptReleaseContext(handle, 0);
        } 
    } 
}

// 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.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution; 
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Diagnostics.CodeAnalysis; 
using System.Diagnostics.Contracts;
 
namespace Microsoft.Win32.SafeHandles { 
    /// 
    ///     SafeHandle for buffers returned by the Axl APIs 
    /// 
    // 
    // 
    //  
#pragma warning disable 618    // Have not migrated to v4 transparency yet
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)] 
#pragma warning restore 618 
    internal sealed class SafeAxlBufferHandle : SafeHandleZeroOrMinusOneIsInvalid {
        private SafeAxlBufferHandle() : base(true) { 
            return;
        }

        [DllImport("kernel32")] 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity] 
        private static extern IntPtr GetProcessHeap(); 

        [DllImport("kernel32")] 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool HeapFree(IntPtr hHeap, int dwFlags, IntPtr lpMem); 

        protected override bool ReleaseHandle() { 
            // _AxlFree is a wrapper around HeapFree on the process heap. Since it is not exported from mscorwks 
            // we just call HeapFree directly. This needs to be updated if _AxlFree is ever changed.
            HeapFree(GetProcessHeap(), 0, handle); 
            return true;
        }
    }
 
    /// 
    ///     SafeHandle for CAPI hash algorithms (HCRYPTHASH) 
    ///  
    // 
    //  
    // 
#pragma warning disable 618    // Have not migrated to v4 transparency yet
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618 
    internal sealed class SafeCapiHashHandle : SafeHandleZeroOrMinusOneIsInvalid {
        private SafeCapiHashHandle() : base(true) { 
        } 

        ///  
        ///     NULL hash handle
        /// 
        public static SafeCapiHashHandle InvalidHandle {
            get { 
                SafeCapiHashHandle handle = new SafeCapiHashHandle();
                handle.SetHandle(IntPtr.Zero); 
                return handle; 
            }
        } 

        [DllImport("advapi32")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity] 
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptDestroyHash(IntPtr hHash); 
 
        protected override bool ReleaseHandle() {
            return CryptDestroyHash(handle); 
        }
    }

    ///  
    ///     SafeHandle for CAPI keys (HCRYPTKEY)
    ///  
    //  
    // 
    //  
#pragma warning disable 618    // Have not migrated to v4 transparency yet
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618
    internal sealed class SafeCapiKeyHandle : SafeHandleZeroOrMinusOneIsInvalid { 
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        private SafeCapiKeyHandle() : base(true) { 
        } 

        ///  
        ///     NULL key handle
        /// 
        internal static SafeCapiKeyHandle InvalidHandle {
            [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
            get {
                SafeCapiKeyHandle handle = new SafeCapiKeyHandle(); 
                handle.SetHandle(IntPtr.Zero); 
                return handle;
            } 
        }

        [DllImport("advapi32")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)] 
        private static extern bool CryptDestroyKey(IntPtr hKey); 

        ///  
        ///     Make a copy of this key handle
        /// 
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        internal SafeCapiKeyHandle Duplicate() { 
            Contract.Requires(!IsInvalid && !IsClosed);
            Contract.Ensures(Contract.Result() != null && !Contract.Result().IsInvalid && !Contract.Result().IsClosed); 
 
            SafeCapiKeyHandle duplicate = null;
            if (!CapiNative.UnsafeNativeMethods.CryptDuplicateKey(this, IntPtr.Zero, 0, out duplicate)) { 
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }

            return duplicate; 
        }
 
        protected override bool ReleaseHandle() { 
            return CryptDestroyKey(handle);
        } 
    }

    /// 
    ///     SafeHandle for crypto service providers (HCRYPTPROV) 
    /// 
    //  
    //  
    // 
#pragma warning disable 618    // Have not migrated to v4 transparency yet 
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618
    internal sealed class SafeCspHandle : SafeHandleZeroOrMinusOneIsInvalid {
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        private SafeCspHandle() : base(true) {
            return; 
        } 

        [DllImport("advapi32", SetLastError = true)] 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptContextAddRef(SafeCspHandle hProv, 
                                                     IntPtr pdwReserved,
                                                     int dwFlags); 
 
        [DllImport("advapi32")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptReleaseContext(IntPtr hProv, int dwFlags);
 
        /// 
        ///     Create a second SafeCspHandle which refers to the same HCRYPTPROV 
        ///  
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        public SafeCspHandle Duplicate() { 
            Contract.Requires(!IsInvalid && !IsClosed);

            // In the window between the call to CryptContextAddRef and when the raw handle value is assigned
            // into this safe handle, there's a second reference to the original safe handle that the CLR does 
            // not know about, so we need to bump the reference count around this entire operation to ensure
            // that we don't have the original handle closed underneath us. 
            bool acquired = false; 
            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                DangerousAddRef(ref acquired);
                IntPtr originalHandle = DangerousGetHandle();

                int error = (int)CapiNative.ErrorCode.Success; 

                SafeCspHandle duplicate = new SafeCspHandle(); 
 
                // A successful call to CryptContextAddRef and an assignment of the handle value to the duplicate
                // SafeHandle need to happen atomically, so we contain them within a CER. 
                RuntimeHelpers.PrepareConstrainedRegions();
                try { }
                finally {
                    if (!CryptContextAddRef(this, IntPtr.Zero, 0)) { 
                        error = Marshal.GetLastWin32Error();
                    } 
                    else { 
                        duplicate.SetHandle(originalHandle);
                    } 
                }

                // If we could not call CryptContextAddRef succesfully, then throw the error here otherwise
                // we should be in a valid state at this point. 
                if (error != (int)CapiNative.ErrorCode.Success) {
                    duplicate.Dispose(); 
                    throw new CryptographicException(error); 
                }
                else { 
                    Debug.Assert(!duplicate.IsInvalid, "Failed to duplicate handle successfully");
                }

                return duplicate; 
            }
            finally { 
                if (acquired) { 
                    DangerousRelease();
                } 
            }
        }

        protected override bool ReleaseHandle() { 
            return CryptReleaseContext(handle, 0);
        } 
    } 
}

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