DataProtection.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / clr / src / ManagedLibraries / Security / System / Security / Cryptography / DataProtection.cs / 1 / DataProtection.cs

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

// 
// DataProtection.cs 
//
// 01/25/2003 
//

namespace System.Security.Cryptography
{ 
    using Microsoft.Win32;
    using System.Runtime.CompilerServices; 
    using System.Runtime.InteropServices; 
    using System.Runtime.ConstrainedExecution;
    using System.Security.Permissions; 
    using System.Globalization;

    public enum DataProtectionScope {
        CurrentUser     = 0x00, 
        LocalMachine    = 0x01
    } 
 
    public enum MemoryProtectionScope {
        SameProcess     = 0x00, 
        CrossProcess    = 0x01,
        SameLogon       = 0x02
    }
 
    [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
    public sealed class ProtectedData { 
        private ProtectedData () {} 

        public static byte[] Protect (byte[] userData, 
                                      byte[] optionalEntropy,
                                      DataProtectionScope scope) {
            if (userData == null)
                throw new ArgumentNullException("userData"); 
            if (Environment.OSVersion.Platform == PlatformID.Win32Windows)
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT")); 
 
            GCHandle pbDataIn = new GCHandle();
            GCHandle pOptionalEntropy = new GCHandle(); 
            CAPI.CRYPTOAPI_BLOB blob = new CAPI.CRYPTOAPI_BLOB();

            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                pbDataIn = GCHandle.Alloc(userData, GCHandleType.Pinned);
                CAPI.CRYPTOAPI_BLOB dataIn = new CAPI.CRYPTOAPI_BLOB(); 
                dataIn.cbData = (uint) userData.Length; 
                dataIn.pbData = pbDataIn.AddrOfPinnedObject();
                CAPI.CRYPTOAPI_BLOB entropy = new CAPI.CRYPTOAPI_BLOB(); 
                if (optionalEntropy != null) {
                    pOptionalEntropy = GCHandle.Alloc(optionalEntropy, GCHandleType.Pinned);
                    entropy.cbData = (uint) optionalEntropy.Length;
                    entropy.pbData = pOptionalEntropy.AddrOfPinnedObject(); 
                }
                uint dwFlags = CAPI.CRYPTPROTECT_UI_FORBIDDEN; 
                if (scope == DataProtectionScope.LocalMachine) 
                    dwFlags |= CAPI.CRYPTPROTECT_LOCAL_MACHINE;
                unsafe { 
                    if (!CAPI.CryptProtectData(new IntPtr(&dataIn),
                                               String.Empty,
                                               new IntPtr(&entropy),
                                               IntPtr.Zero, 
                                               IntPtr.Zero,
                                               dwFlags, 
                                               new IntPtr(&blob))) 
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                } 

                // In some cases, the API would fail due to OOM but simply return a null pointer.
                if (blob.pbData == IntPtr.Zero)
                    throw new OutOfMemoryException(); 

                byte[] encryptedData = new byte[(int) blob.cbData]; 
                Marshal.Copy(blob.pbData, encryptedData, 0, encryptedData.Length); 

                return encryptedData; 
            }
            catch (EntryPointNotFoundException) {
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
            } 
            finally {
                if (pbDataIn.IsAllocated) 
                   pbDataIn.Free(); 
                if (pOptionalEntropy.IsAllocated)
                   pOptionalEntropy.Free(); 
                if (blob.pbData != IntPtr.Zero) {
                    CAPI.ZeroMemory(blob.pbData, blob.cbData);
                    CAPI.LocalFree(blob.pbData);
                } 
            }
        } 
 
        public static byte[] Unprotect (byte[] encryptedData,
                                        byte[] optionalEntropy, 
                                        DataProtectionScope scope) {
            if (encryptedData == null)
                throw new ArgumentNullException("encryptedData");
            if (Environment.OSVersion.Platform == PlatformID.Win32Windows) 
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
 
            GCHandle pbDataIn = new GCHandle(); 
            GCHandle pOptionalEntropy = new GCHandle();
            CAPI.CRYPTOAPI_BLOB userData = new CAPI.CRYPTOAPI_BLOB(); 

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                pbDataIn = GCHandle.Alloc(encryptedData, GCHandleType.Pinned); 
                CAPI.CRYPTOAPI_BLOB dataIn = new CAPI.CRYPTOAPI_BLOB();
                dataIn.cbData = (uint) encryptedData.Length; 
                dataIn.pbData = pbDataIn.AddrOfPinnedObject(); 
                CAPI.CRYPTOAPI_BLOB entropy = new CAPI.CRYPTOAPI_BLOB();
                if (optionalEntropy != null) { 
                    pOptionalEntropy = GCHandle.Alloc(optionalEntropy, GCHandleType.Pinned);
                    entropy.cbData = (uint) optionalEntropy.Length;
                    entropy.pbData = pOptionalEntropy.AddrOfPinnedObject();
                } 
                uint dwFlags = CAPI.CRYPTPROTECT_UI_FORBIDDEN;
                if (scope == DataProtectionScope.LocalMachine) 
                    dwFlags |= CAPI.CRYPTPROTECT_LOCAL_MACHINE; 
                unsafe {
                    if (!CAPI.CryptUnprotectData(new IntPtr(&dataIn), 
                                                 IntPtr.Zero,
                                                 new IntPtr(&entropy),
                                                 IntPtr.Zero,
                                                 IntPtr.Zero, 
                                                 dwFlags,
                                                 new IntPtr(&userData))) 
                        throw new CryptographicException(Marshal.GetLastWin32Error()); 
                }
 
                // In some cases, the API would fail due to OOM but simply return a null pointer.
                if (userData.pbData == IntPtr.Zero)
                    throw new OutOfMemoryException();
 
                byte[] data = new byte[(int) userData.cbData];
                Marshal.Copy(userData.pbData, data, 0, data.Length); 
 
                return data;
            } 
            catch (EntryPointNotFoundException) {
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
            }
            finally { 
                if (pbDataIn.IsAllocated)
                   pbDataIn.Free(); 
                if (pOptionalEntropy.IsAllocated) 
                   pOptionalEntropy.Free();
                if (userData.pbData != IntPtr.Zero) { 
                    CAPI.ZeroMemory(userData.pbData, userData.cbData);
                    CAPI.LocalFree(userData.pbData);
                }
            } 
        }
    } 
 
    [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
    public sealed class ProtectedMemory { 
        private ProtectedMemory () {}

        public static void Protect (byte[] userData,
                                    MemoryProtectionScope scope) { 
            if (userData == null)
                throw new ArgumentNullException("userData"); 
            if (Environment.OSVersion.Platform == PlatformID.Win32Windows) 
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
 
            VerifyScope(scope);

            // The RtlEncryptMemory and RtlDecryptMemory functions are available on WinXP and publicly published
            // in the ntsecapi.h header file as of Windows Server 2003. 
            // The Rtl functions accept data in 8 byte increments, but we don't want applications to be able to make use of this,
            // or else they're liable to break when the user upgrades. 
            if ((userData.Length == 0) || (userData.Length % CAPI.CRYPTPROTECTMEMORY_BLOCK_SIZE != 0)) 
                throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_DpApi_InvalidMemoryLength"));
 
            uint dwFlags = (uint) scope;
            try {
                // RtlEncryptMemory return an NTSTATUS
                int status = CAPI.SystemFunction040(userData, 
                                                    (uint) userData.Length,
                                                    dwFlags); 
                if (status < 0) // non-negative numbers indicate success 
                    throw new CryptographicException(CAPI.LsaNtStatusToWinError(status));
            } 
            catch (EntryPointNotFoundException) {
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
            }
        } 

        public static void Unprotect (byte[] encryptedData, 
                                      MemoryProtectionScope scope) { 
            if (encryptedData == null)
                throw new ArgumentNullException("encryptedData"); 
            if (Environment.OSVersion.Platform == PlatformID.Win32Windows)
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));

            VerifyScope(scope); 

            // The RtlEncryptMemory and RtlDecryptMemory functions are available on WinXP and publicly published 
            // in the ntsecapi.h header file as of Windows Server 2003. 
            // The Rtl functions accept data in 8 byte increments, but we don't want applications to be able to make use of this,
            // or else they're liable to break when the user upgrades. 
            if ((encryptedData.Length == 0) || (encryptedData.Length % CAPI.CRYPTPROTECTMEMORY_BLOCK_SIZE != 0))
                throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_DpApi_InvalidMemoryLength"));

            uint dwFlags = (uint) scope; 
            try {
                // RtlDecryptMemory return an NTSTATUS 
                int status = CAPI.SystemFunction041(encryptedData, 
                                                    (uint) encryptedData.Length,
                                                    dwFlags); 
                if (status < 0) // non-negative numbers indicate success
                    throw new CryptographicException(CAPI.LsaNtStatusToWinError(status));
            }
            catch (EntryPointNotFoundException) { 
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
            } 
        } 

        private static void VerifyScope (MemoryProtectionScope scope) { 
            if ((scope != MemoryProtectionScope.SameProcess) && (scope != MemoryProtectionScope.CrossProcess) &&
                (scope != MemoryProtectionScope.SameLogon))
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SecurityResources.GetResourceString("Arg_EnumIllegalVal"), (int) scope));
        } 
    }
} 

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

// 
// DataProtection.cs 
//
// 01/25/2003 
//

namespace System.Security.Cryptography
{ 
    using Microsoft.Win32;
    using System.Runtime.CompilerServices; 
    using System.Runtime.InteropServices; 
    using System.Runtime.ConstrainedExecution;
    using System.Security.Permissions; 
    using System.Globalization;

    public enum DataProtectionScope {
        CurrentUser     = 0x00, 
        LocalMachine    = 0x01
    } 
 
    public enum MemoryProtectionScope {
        SameProcess     = 0x00, 
        CrossProcess    = 0x01,
        SameLogon       = 0x02
    }
 
    [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
    public sealed class ProtectedData { 
        private ProtectedData () {} 

        public static byte[] Protect (byte[] userData, 
                                      byte[] optionalEntropy,
                                      DataProtectionScope scope) {
            if (userData == null)
                throw new ArgumentNullException("userData"); 
            if (Environment.OSVersion.Platform == PlatformID.Win32Windows)
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT")); 
 
            GCHandle pbDataIn = new GCHandle();
            GCHandle pOptionalEntropy = new GCHandle(); 
            CAPI.CRYPTOAPI_BLOB blob = new CAPI.CRYPTOAPI_BLOB();

            RuntimeHelpers.PrepareConstrainedRegions();
            try { 
                pbDataIn = GCHandle.Alloc(userData, GCHandleType.Pinned);
                CAPI.CRYPTOAPI_BLOB dataIn = new CAPI.CRYPTOAPI_BLOB(); 
                dataIn.cbData = (uint) userData.Length; 
                dataIn.pbData = pbDataIn.AddrOfPinnedObject();
                CAPI.CRYPTOAPI_BLOB entropy = new CAPI.CRYPTOAPI_BLOB(); 
                if (optionalEntropy != null) {
                    pOptionalEntropy = GCHandle.Alloc(optionalEntropy, GCHandleType.Pinned);
                    entropy.cbData = (uint) optionalEntropy.Length;
                    entropy.pbData = pOptionalEntropy.AddrOfPinnedObject(); 
                }
                uint dwFlags = CAPI.CRYPTPROTECT_UI_FORBIDDEN; 
                if (scope == DataProtectionScope.LocalMachine) 
                    dwFlags |= CAPI.CRYPTPROTECT_LOCAL_MACHINE;
                unsafe { 
                    if (!CAPI.CryptProtectData(new IntPtr(&dataIn),
                                               String.Empty,
                                               new IntPtr(&entropy),
                                               IntPtr.Zero, 
                                               IntPtr.Zero,
                                               dwFlags, 
                                               new IntPtr(&blob))) 
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                } 

                // In some cases, the API would fail due to OOM but simply return a null pointer.
                if (blob.pbData == IntPtr.Zero)
                    throw new OutOfMemoryException(); 

                byte[] encryptedData = new byte[(int) blob.cbData]; 
                Marshal.Copy(blob.pbData, encryptedData, 0, encryptedData.Length); 

                return encryptedData; 
            }
            catch (EntryPointNotFoundException) {
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
            } 
            finally {
                if (pbDataIn.IsAllocated) 
                   pbDataIn.Free(); 
                if (pOptionalEntropy.IsAllocated)
                   pOptionalEntropy.Free(); 
                if (blob.pbData != IntPtr.Zero) {
                    CAPI.ZeroMemory(blob.pbData, blob.cbData);
                    CAPI.LocalFree(blob.pbData);
                } 
            }
        } 
 
        public static byte[] Unprotect (byte[] encryptedData,
                                        byte[] optionalEntropy, 
                                        DataProtectionScope scope) {
            if (encryptedData == null)
                throw new ArgumentNullException("encryptedData");
            if (Environment.OSVersion.Platform == PlatformID.Win32Windows) 
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
 
            GCHandle pbDataIn = new GCHandle(); 
            GCHandle pOptionalEntropy = new GCHandle();
            CAPI.CRYPTOAPI_BLOB userData = new CAPI.CRYPTOAPI_BLOB(); 

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                pbDataIn = GCHandle.Alloc(encryptedData, GCHandleType.Pinned); 
                CAPI.CRYPTOAPI_BLOB dataIn = new CAPI.CRYPTOAPI_BLOB();
                dataIn.cbData = (uint) encryptedData.Length; 
                dataIn.pbData = pbDataIn.AddrOfPinnedObject(); 
                CAPI.CRYPTOAPI_BLOB entropy = new CAPI.CRYPTOAPI_BLOB();
                if (optionalEntropy != null) { 
                    pOptionalEntropy = GCHandle.Alloc(optionalEntropy, GCHandleType.Pinned);
                    entropy.cbData = (uint) optionalEntropy.Length;
                    entropy.pbData = pOptionalEntropy.AddrOfPinnedObject();
                } 
                uint dwFlags = CAPI.CRYPTPROTECT_UI_FORBIDDEN;
                if (scope == DataProtectionScope.LocalMachine) 
                    dwFlags |= CAPI.CRYPTPROTECT_LOCAL_MACHINE; 
                unsafe {
                    if (!CAPI.CryptUnprotectData(new IntPtr(&dataIn), 
                                                 IntPtr.Zero,
                                                 new IntPtr(&entropy),
                                                 IntPtr.Zero,
                                                 IntPtr.Zero, 
                                                 dwFlags,
                                                 new IntPtr(&userData))) 
                        throw new CryptographicException(Marshal.GetLastWin32Error()); 
                }
 
                // In some cases, the API would fail due to OOM but simply return a null pointer.
                if (userData.pbData == IntPtr.Zero)
                    throw new OutOfMemoryException();
 
                byte[] data = new byte[(int) userData.cbData];
                Marshal.Copy(userData.pbData, data, 0, data.Length); 
 
                return data;
            } 
            catch (EntryPointNotFoundException) {
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
            }
            finally { 
                if (pbDataIn.IsAllocated)
                   pbDataIn.Free(); 
                if (pOptionalEntropy.IsAllocated) 
                   pOptionalEntropy.Free();
                if (userData.pbData != IntPtr.Zero) { 
                    CAPI.ZeroMemory(userData.pbData, userData.cbData);
                    CAPI.LocalFree(userData.pbData);
                }
            } 
        }
    } 
 
    [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
    public sealed class ProtectedMemory { 
        private ProtectedMemory () {}

        public static void Protect (byte[] userData,
                                    MemoryProtectionScope scope) { 
            if (userData == null)
                throw new ArgumentNullException("userData"); 
            if (Environment.OSVersion.Platform == PlatformID.Win32Windows) 
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
 
            VerifyScope(scope);

            // The RtlEncryptMemory and RtlDecryptMemory functions are available on WinXP and publicly published
            // in the ntsecapi.h header file as of Windows Server 2003. 
            // The Rtl functions accept data in 8 byte increments, but we don't want applications to be able to make use of this,
            // or else they're liable to break when the user upgrades. 
            if ((userData.Length == 0) || (userData.Length % CAPI.CRYPTPROTECTMEMORY_BLOCK_SIZE != 0)) 
                throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_DpApi_InvalidMemoryLength"));
 
            uint dwFlags = (uint) scope;
            try {
                // RtlEncryptMemory return an NTSTATUS
                int status = CAPI.SystemFunction040(userData, 
                                                    (uint) userData.Length,
                                                    dwFlags); 
                if (status < 0) // non-negative numbers indicate success 
                    throw new CryptographicException(CAPI.LsaNtStatusToWinError(status));
            } 
            catch (EntryPointNotFoundException) {
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
            }
        } 

        public static void Unprotect (byte[] encryptedData, 
                                      MemoryProtectionScope scope) { 
            if (encryptedData == null)
                throw new ArgumentNullException("encryptedData"); 
            if (Environment.OSVersion.Platform == PlatformID.Win32Windows)
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));

            VerifyScope(scope); 

            // The RtlEncryptMemory and RtlDecryptMemory functions are available on WinXP and publicly published 
            // in the ntsecapi.h header file as of Windows Server 2003. 
            // The Rtl functions accept data in 8 byte increments, but we don't want applications to be able to make use of this,
            // or else they're liable to break when the user upgrades. 
            if ((encryptedData.Length == 0) || (encryptedData.Length % CAPI.CRYPTPROTECTMEMORY_BLOCK_SIZE != 0))
                throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_DpApi_InvalidMemoryLength"));

            uint dwFlags = (uint) scope; 
            try {
                // RtlDecryptMemory return an NTSTATUS 
                int status = CAPI.SystemFunction041(encryptedData, 
                                                    (uint) encryptedData.Length,
                                                    dwFlags); 
                if (status < 0) // non-negative numbers indicate success
                    throw new CryptographicException(CAPI.LsaNtStatusToWinError(status));
            }
            catch (EntryPointNotFoundException) { 
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
            } 
        } 

        private static void VerifyScope (MemoryProtectionScope scope) { 
            if ((scope != MemoryProtectionScope.SameProcess) && (scope != MemoryProtectionScope.CrossProcess) &&
                (scope != MemoryProtectionScope.SameLogon))
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, SecurityResources.GetResourceString("Arg_EnumIllegalVal"), (int) scope));
        } 
    }
} 

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