diff options
Diffstat (limited to 'src/mscorlib/src/System/Security/securestring.cs')
-rw-r--r-- | src/mscorlib/src/System/Security/securestring.cs | 751 |
1 files changed, 0 insertions, 751 deletions
diff --git a/src/mscorlib/src/System/Security/securestring.cs b/src/mscorlib/src/System/Security/securestring.cs deleted file mode 100644 index 548126f4d0..0000000000 --- a/src/mscorlib/src/System/Security/securestring.cs +++ /dev/null @@ -1,751 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -namespace System.Security { - using System.Security.Cryptography; - using System.Runtime.InteropServices; -#if FEATURE_CORRUPTING_EXCEPTIONS - using System.Runtime.ExceptionServices; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - using System.Text; - using Microsoft.Win32; - using System.Runtime.CompilerServices; - using System.Security.Permissions; - using System.Runtime.ConstrainedExecution; - using System.Runtime.Versioning; - using Microsoft.Win32.SafeHandles; - using System.Diagnostics; - using System.Diagnostics.Contracts; - - public sealed class SecureString: IDisposable { - [System.Security.SecurityCritical] // auto-generated - private SafeBSTRHandle m_buffer; - [ContractPublicPropertyName("Length")] - private int m_length; - private bool m_readOnly; - private bool m_encrypted; - - static bool supportedOnCurrentPlatform = EncryptionSupported(); - - const int BlockSize = (int)Win32Native.CRYPTPROTECTMEMORY_BLOCK_SIZE /2; // a char is two bytes - const int MaxLength = 65536; - const uint ProtectionScope = Win32Native.CRYPTPROTECTMEMORY_SAME_PROCESS; - - [System.Security.SecuritySafeCritical] // auto-generated - static SecureString() - { - } - - [System.Security.SecurityCritical] // auto-generated - unsafe static bool EncryptionSupported() { - // check if the enrypt/decrypt function is supported on current OS - bool supported = true; - try { - Win32Native.SystemFunction041( - SafeBSTRHandle.Allocate(null , (int)Win32Native.CRYPTPROTECTMEMORY_BLOCK_SIZE), - Win32Native.CRYPTPROTECTMEMORY_BLOCK_SIZE, - Win32Native.CRYPTPROTECTMEMORY_SAME_PROCESS); - } - catch (EntryPointNotFoundException) { - supported = false; - } - return supported; - } - - [System.Security.SecurityCritical] // auto-generated - internal SecureString(SecureString str) { - AllocateBuffer(str.BufferLength); - SafeBSTRHandle.Copy(str.m_buffer, this.m_buffer); - m_length = str.m_length; - m_encrypted = str.m_encrypted; - } - - - [System.Security.SecuritySafeCritical] // auto-generated - public SecureString() { - CheckSupportedOnCurrentPlatform(); - - // allocate the minimum block size for calling protectMemory - AllocateBuffer(BlockSize); - m_length = 0; - } - - - [System.Security.SecurityCritical] // auto-generated -#if FEATURE_CORRUPTING_EXCEPTIONS - [HandleProcessCorruptedStateExceptions] -#endif // FEATURE_CORRUPTING_EXCEPTIONS - private unsafe void InitializeSecureString(char* value, int length) - { - CheckSupportedOnCurrentPlatform(); - - AllocateBuffer(length); - m_length = length; - - byte* bufferPtr = null; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - m_buffer.AcquirePointer(ref bufferPtr); - Buffer.Memcpy(bufferPtr, (byte*)value, length * 2); - } - catch (Exception) { - ProtectMemory(); - throw; - } - finally - { - if (bufferPtr != null) - m_buffer.ReleasePointer(); - } - - ProtectMemory(); - } - - [System.Security.SecurityCritical] // auto-generated - [CLSCompliant(false)] - public unsafe SecureString(char* value, int length) { - if( value == null) { - throw new ArgumentNullException(nameof(value)); - } - - if( length < 0) { - throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); - } - - if( length > MaxLength) { - throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Length")); - } - Contract.EndContractBlock(); - - // Refactored since HandleProcessCorruptedStateExceptionsAttribute applies to methods only (yet). - InitializeSecureString(value, length); - } - - public int Length { - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] - get { - EnsureNotDisposed(); - return m_length; - } - } - - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] -#if FEATURE_CORRUPTING_EXCEPTIONS - [HandleProcessCorruptedStateExceptions] -#endif // FEATURE_CORRUPTING_EXCEPTIONS - public void AppendChar(char c) { - EnsureNotDisposed(); - EnsureNotReadOnly(); - - EnsureCapacity(m_length + 1); - - RuntimeHelpers.PrepareConstrainedRegions(); - try { - UnProtectMemory(); - m_buffer.Write<char>((uint)m_length * sizeof(char), c); - m_length++; - } - catch (Exception) { - ProtectMemory(); - throw; - } - finally { - ProtectMemory(); - } - } - - // clears the current contents. Only available if writable - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public void Clear() { - EnsureNotDisposed(); - EnsureNotReadOnly(); - - m_length = 0; - m_buffer.ClearBuffer(); - m_encrypted = false; - } - - // Do a deep-copy of the SecureString - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public SecureString Copy() { - EnsureNotDisposed(); - return new SecureString(this); - } - - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public void Dispose() { - if(m_buffer != null && !m_buffer.IsInvalid) { - m_buffer.Close(); - m_buffer = null; - } - } - - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] -#if FEATURE_CORRUPTING_EXCEPTIONS - [HandleProcessCorruptedStateExceptions] -#endif // FEATURE_CORRUPTING_EXCEPTIONS - public void InsertAt( int index, char c ) { - if( index < 0 || index > m_length) { - throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexString")); - } - Contract.EndContractBlock(); - - EnsureNotDisposed(); - EnsureNotReadOnly(); - - EnsureCapacity(m_length + 1); - - unsafe { - byte* bufferPtr = null; - RuntimeHelpers.PrepareConstrainedRegions(); - try { - UnProtectMemory(); - m_buffer.AcquirePointer(ref bufferPtr); - char* pBuffer = (char*)bufferPtr; - - for (int i = m_length; i > index; i--) { - pBuffer[i] = pBuffer[i - 1]; - } - pBuffer[index] = c; - ++m_length; - } - catch (Exception) { - ProtectMemory(); - throw; - } - finally { - ProtectMemory(); - if (bufferPtr != null) - m_buffer.ReleasePointer(); - } - } - } - - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public bool IsReadOnly() { - EnsureNotDisposed(); - return m_readOnly; - } - - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] - public void MakeReadOnly() { - EnsureNotDisposed(); - m_readOnly = true; - } - - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] -#if FEATURE_CORRUPTING_EXCEPTIONS - [HandleProcessCorruptedStateExceptions] -#endif // FEATURE_CORRUPTING_EXCEPTIONS - public void RemoveAt( int index ) { - EnsureNotDisposed(); - EnsureNotReadOnly(); - - if( index < 0 || index >= m_length) { - throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexString")); - } - - unsafe - { - byte* bufferPtr = null; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - UnProtectMemory(); - m_buffer.AcquirePointer(ref bufferPtr); - char* pBuffer = (char*)bufferPtr; - - for (int i = index; i < m_length - 1; i++) - { - pBuffer[i] = pBuffer[i + 1]; - } - pBuffer[--m_length] = (char)0; - } - catch (Exception) { - ProtectMemory(); - throw; - } - finally - { - ProtectMemory(); - if (bufferPtr != null) - m_buffer.ReleasePointer(); - } - } - } - - [System.Security.SecuritySafeCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] -#if FEATURE_CORRUPTING_EXCEPTIONS - [HandleProcessCorruptedStateExceptions] -#endif // FEATURE_CORRUPTING_EXCEPTIONS - public void SetAt( int index, char c ) { - if( index < 0 || index >= m_length) { - throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexString")); - } - Contract.EndContractBlock(); - Debug.Assert(index <= Int32.MaxValue / sizeof(char)); - - EnsureNotDisposed(); - EnsureNotReadOnly(); - - RuntimeHelpers.PrepareConstrainedRegions(); - try { - UnProtectMemory(); - m_buffer.Write<char>((uint)index * sizeof(char), c); - } - catch (Exception) { - ProtectMemory(); - throw; - } - finally { - ProtectMemory(); - } - } - - private int BufferLength { - [System.Security.SecurityCritical] // auto-generated - get { - Debug.Assert(m_buffer != null, "Buffer is not initialized!"); - return m_buffer.Length; - } - } - - [System.Security.SecurityCritical] // auto-generated - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - private void AllocateBuffer(int size) { - uint alignedSize = GetAlignedSize(size); - - m_buffer = SafeBSTRHandle.Allocate(null, alignedSize); - if (m_buffer.IsInvalid) { - throw new OutOfMemoryException(); - } - } - - private void CheckSupportedOnCurrentPlatform() { - if( !supportedOnCurrentPlatform) { - throw new NotSupportedException(Environment.GetResourceString("Arg_PlatformSecureString")); - } - Contract.EndContractBlock(); - } - - [System.Security.SecurityCritical] // auto-generated - private void EnsureCapacity(int capacity) { - if( capacity > MaxLength) { - throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_Capacity")); - } - Contract.EndContractBlock(); - - if( capacity <= m_buffer.Length) { - return; - } - - SafeBSTRHandle newBuffer = SafeBSTRHandle.Allocate(null, GetAlignedSize(capacity)); - - if (newBuffer.IsInvalid) { - throw new OutOfMemoryException(); - } - - SafeBSTRHandle.Copy(m_buffer, newBuffer); - m_buffer.Close(); - m_buffer = newBuffer; - } - - [System.Security.SecurityCritical] // auto-generated - private void EnsureNotDisposed() { - if( m_buffer == null) { - throw new ObjectDisposedException(null); - } - Contract.EndContractBlock(); - } - - private void EnsureNotReadOnly() { - if( m_readOnly) { - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly")); - } - Contract.EndContractBlock(); - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - private static uint GetAlignedSize( int size) { - Debug.Assert(size >= 0, "size must be non-negative"); - - uint alignedSize = ((uint)size / BlockSize) * BlockSize; - if( (size % BlockSize != 0) || size == 0) { // if size is 0, set allocated size to blocksize - alignedSize += BlockSize; - } - return alignedSize; - } - - [System.Security.SecurityCritical] // auto-generated - private unsafe int GetAnsiByteCount() { - const uint CP_ACP = 0; - const uint WC_NO_BEST_FIT_CHARS = 0x00000400; - - uint flgs = WC_NO_BEST_FIT_CHARS; - uint DefaultCharUsed = (uint)'?'; - - byte* bufferPtr = null; - RuntimeHelpers.PrepareConstrainedRegions(); - try { - m_buffer.AcquirePointer(ref bufferPtr); - - return Win32Native.WideCharToMultiByte( - CP_ACP, - flgs, - (char*) bufferPtr, - m_length, - null, - 0, - IntPtr.Zero, - new IntPtr((void*)&DefaultCharUsed)); - } - finally { - if (bufferPtr != null) - m_buffer.ReleasePointer(); - } - } - - [System.Security.SecurityCritical] // auto-generated - private unsafe void GetAnsiBytes( byte * ansiStrPtr, int byteCount) { - const uint CP_ACP = 0; - const uint WC_NO_BEST_FIT_CHARS = 0x00000400; - - uint flgs = WC_NO_BEST_FIT_CHARS; - uint DefaultCharUsed = (uint)'?'; - - byte* bufferPtr = null; - RuntimeHelpers.PrepareConstrainedRegions(); - try { - m_buffer.AcquirePointer(ref bufferPtr); - - Win32Native.WideCharToMultiByte( - CP_ACP, - flgs, - (char*) bufferPtr, - m_length, - ansiStrPtr, - byteCount - 1, - IntPtr.Zero, - new IntPtr((void*)&DefaultCharUsed)); - - *(ansiStrPtr + byteCount - 1) = (byte)0; - } - finally { - if (bufferPtr != null) - m_buffer.ReleasePointer(); - } - } - - [System.Security.SecurityCritical] // auto-generated - [ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)] - private void ProtectMemory() { - Debug.Assert(!m_buffer.IsInvalid && m_buffer.Length != 0, "Invalid buffer!"); - Debug.Assert(m_buffer.Length % BlockSize == 0, "buffer length must be multiple of blocksize!"); - - if( m_length == 0 || m_encrypted) { - return; - } - - RuntimeHelpers.PrepareConstrainedRegions(); - try { - } - finally { - // RtlEncryptMemory return an NTSTATUS - int status = Win32Native.SystemFunction040(m_buffer, (uint)m_buffer.Length * 2, ProtectionScope); - if (status < 0) { // non-negative numbers indicate success -#if FEATURE_CORECLR - throw new CryptographicException(Win32Native.RtlNtStatusToDosError(status)); -#else - throw new CryptographicException(Win32Native.LsaNtStatusToWinError(status)); -#endif - } - m_encrypted = true; - } - } - - [System.Security.SecurityCritical] // auto-generated - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - [MethodImplAttribute(MethodImplOptions.Synchronized)] -#if FEATURE_CORRUPTING_EXCEPTIONS - [HandleProcessCorruptedStateExceptions] -#endif // FEATURE_CORRUPTING_EXCEPTIONS - internal unsafe IntPtr ToBSTR() { - EnsureNotDisposed(); - int length = m_length; - IntPtr ptr = IntPtr.Zero; - IntPtr result = IntPtr.Zero; - byte* bufferPtr = null; - - RuntimeHelpers.PrepareConstrainedRegions(); - try { - RuntimeHelpers.PrepareConstrainedRegions(); - try { - } - finally { - ptr = Win32Native.SysAllocStringLen(null, length); - } - - if (ptr == IntPtr.Zero) { - throw new OutOfMemoryException(); - } - - UnProtectMemory(); - m_buffer.AcquirePointer(ref bufferPtr); - Buffer.Memcpy((byte*) ptr.ToPointer(), bufferPtr, length *2); - result = ptr; - } - catch (Exception) { - ProtectMemory(); - throw; - } - finally { - ProtectMemory(); - if( result == IntPtr.Zero) { - // If we failed for any reason, free the new buffer - if (ptr != IntPtr.Zero) { - Win32Native.ZeroMemory(ptr, (UIntPtr)(length * 2)); - Win32Native.SysFreeString(ptr); - } - } - if (bufferPtr != null) - m_buffer.ReleasePointer(); - } - return result; - } - - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] -#if FEATURE_CORRUPTING_EXCEPTIONS - [HandleProcessCorruptedStateExceptions] -#endif // FEATURE_CORRUPTING_EXCEPTIONS - internal unsafe IntPtr ToUniStr(bool allocateFromHeap) { - EnsureNotDisposed(); - int length = m_length; - IntPtr ptr = IntPtr.Zero; - IntPtr result = IntPtr.Zero; - byte* bufferPtr = null; - - RuntimeHelpers.PrepareConstrainedRegions(); - try { - RuntimeHelpers.PrepareConstrainedRegions(); - try { - } - finally { - if( allocateFromHeap) { - ptr = Marshal.AllocHGlobal((length + 1) * 2); - } - else { - ptr = Marshal.AllocCoTaskMem((length + 1) * 2); - } - } - - if (ptr == IntPtr.Zero) { - throw new OutOfMemoryException(); - } - - UnProtectMemory(); - m_buffer.AcquirePointer(ref bufferPtr); - Buffer.Memcpy((byte*) ptr.ToPointer(), bufferPtr, length *2); - char * endptr = (char *) ptr.ToPointer(); - *(endptr + length) = '\0'; - result = ptr; - } - catch (Exception) { - ProtectMemory(); - throw; - } - finally { - ProtectMemory(); - - if( result == IntPtr.Zero) { - // If we failed for any reason, free the new buffer - if (ptr != IntPtr.Zero) { - Win32Native.ZeroMemory(ptr, (UIntPtr)(length * 2)); - if( allocateFromHeap) { - Marshal.FreeHGlobal(ptr); - } - else { - Marshal.FreeCoTaskMem(ptr); - } - } - } - - if (bufferPtr != null) - m_buffer.ReleasePointer(); - } - return result; - } - - [System.Security.SecurityCritical] // auto-generated - [MethodImplAttribute(MethodImplOptions.Synchronized)] -#if FEATURE_CORRUPTING_EXCEPTIONS - [HandleProcessCorruptedStateExceptions] -#endif // FEATURE_CORRUPTING_EXCEPTIONS - internal unsafe IntPtr ToAnsiStr(bool allocateFromHeap) { - EnsureNotDisposed(); - - IntPtr ptr = IntPtr.Zero; - IntPtr result = IntPtr.Zero; - int byteCount = 0; - RuntimeHelpers.PrepareConstrainedRegions(); - try { - // GetAnsiByteCount uses the string data, so the calculation must happen after we are decrypted. - UnProtectMemory(); - - // allocating an extra char for terminating zero - byteCount = GetAnsiByteCount() + 1; - - RuntimeHelpers.PrepareConstrainedRegions(); - try { - } - finally { - if( allocateFromHeap) { - ptr = Marshal.AllocHGlobal(byteCount); - } - else { - ptr = Marshal.AllocCoTaskMem(byteCount); - } - } - - if (ptr == IntPtr.Zero) { - throw new OutOfMemoryException(); - } - - GetAnsiBytes((byte *)ptr.ToPointer(), byteCount); - result = ptr; - } - catch (Exception) { - ProtectMemory(); - throw; - } - finally { - ProtectMemory(); - if( result == IntPtr.Zero) { - // If we failed for any reason, free the new buffer - if (ptr != IntPtr.Zero) { - Win32Native.ZeroMemory(ptr, (UIntPtr)byteCount); - if( allocateFromHeap) { - Marshal.FreeHGlobal(ptr); - } - else { - Marshal.FreeCoTaskMem(ptr); - } - } - } - - } - return result; - } - - [System.Security.SecurityCritical] // auto-generated - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - private void UnProtectMemory() { - Debug.Assert(!m_buffer.IsInvalid && m_buffer.Length != 0, "Invalid buffer!"); - Debug.Assert(m_buffer.Length % BlockSize == 0, "buffer length must be multiple of blocksize!"); - - if( m_length == 0) { - return; - } - - RuntimeHelpers.PrepareConstrainedRegions(); - try { - } - finally { - if (m_encrypted) { - // RtlEncryptMemory return an NTSTATUS - int status = Win32Native.SystemFunction041(m_buffer, (uint)m_buffer.Length * 2, ProtectionScope); - if (status < 0) - { // non-negative numbers indicate success -#if FEATURE_CORECLR - throw new CryptographicException(Win32Native.RtlNtStatusToDosError(status)); -#else - throw new CryptographicException(Win32Native.LsaNtStatusToWinError(status)); -#endif - } - m_encrypted = false; - } - } - } - } - - [System.Security.SecurityCritical] // auto-generated - [SuppressUnmanagedCodeSecurityAttribute()] - internal sealed class SafeBSTRHandle : SafeBuffer { - internal SafeBSTRHandle () : base(true) {} - - internal static SafeBSTRHandle Allocate(String src, uint len) - { - SafeBSTRHandle bstr = SysAllocStringLen(src, len); - bstr.Initialize(len * sizeof(char)); - return bstr; - } - - [DllImport(Win32Native.OLEAUT32, CharSet = CharSet.Unicode)] - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] - private static extern SafeBSTRHandle SysAllocStringLen(String src, uint len); // BSTR - - [System.Security.SecurityCritical] - override protected bool ReleaseHandle() - { - Win32Native.ZeroMemory(handle, (UIntPtr) (Win32Native.SysStringLen(handle) * 2)); - Win32Native.SysFreeString(handle); - return true; - } - - [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] - internal unsafe void ClearBuffer() { - byte* bufferPtr = null; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - AcquirePointer(ref bufferPtr); - Win32Native.ZeroMemory((IntPtr)bufferPtr, (UIntPtr) (Win32Native.SysStringLen((IntPtr)bufferPtr) * 2)); - } - finally - { - if (bufferPtr != null) - ReleasePointer(); - } - } - - - internal unsafe int Length { - get { - return (int) Win32Native.SysStringLen(this); - } - } - - internal unsafe static void Copy(SafeBSTRHandle source, SafeBSTRHandle target) { - byte* sourcePtr = null, targetPtr = null; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - source.AcquirePointer(ref sourcePtr); - target.AcquirePointer(ref targetPtr); - - Debug.Assert(Win32Native.SysStringLen((IntPtr)targetPtr) >= Win32Native.SysStringLen((IntPtr)sourcePtr), "Target buffer is not large enough!"); - - Buffer.Memcpy(targetPtr, sourcePtr, (int) Win32Native.SysStringLen((IntPtr)sourcePtr) * 2); - } - finally - { - if (sourcePtr != null) - source.ReleasePointer(); - if (targetPtr != null) - target.ReleasePointer(); - } - } - } -} - |