예제 #1
0
        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.CAPISafe.LsaNtStatusToWinError(status));
                }
            }
            catch (EntryPointNotFoundException) {
                throw new NotSupportedException(SecurityResources.GetResourceString("NotSupported_PlatformRequiresNT"));
            }
        }