Expose the Marshal APIs that use SecureString
authorAlex Ghiondea <ghiondea.alexandru@microsoft.com>
Thu, 3 Nov 2016 23:45:49 +0000 (16:45 -0700)
committerAlex Ghiondea <ghiondea.alexandru@microsoft.com>
Fri, 4 Nov 2016 22:20:48 +0000 (15:20 -0700)
Commit migrated from https://github.com/dotnet/coreclr/commit/ba53b097df52a8b7a34600cf620d88b554a96cbe

src/coreclr/src/mscorlib/corefx/System/Security/SecureString.Windows.cs
src/coreclr/src/mscorlib/model.xml
src/coreclr/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs

index 98b6de3..5f56353 100644 (file)
@@ -5,6 +5,7 @@
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Security.Cryptography;
+using Microsoft.Win32;
 
 namespace System.Security
 {
@@ -143,6 +144,47 @@ namespace System.Security
             }
         }
 
+        internal unsafe IntPtr MarshalToBSTR()
+        {
+            int length = _decryptedLength;
+            IntPtr ptr = IntPtr.Zero;
+            IntPtr result = IntPtr.Zero;
+            byte* bufferPtr = null;
+
+            UnprotectMemory();
+            try
+            {
+                _buffer.AcquirePointer(ref bufferPtr);
+                int resultByteLength = (length + 1) * sizeof(char);
+
+                ptr = Win32Native.SysAllocStringLen(null, length);
+                if (ptr == IntPtr.Zero) {
+                    throw new OutOfMemoryException();
+                }
+
+                Buffer.MemoryCopy(bufferPtr, (byte*)ptr, resultByteLength, length * sizeof(char));
+
+                result = ptr;
+            }
+            finally
+            {
+                ProtectMemory();
+
+                // If we failed for any reason, free the new buffer
+                if (result == IntPtr.Zero && ptr != IntPtr.Zero)
+                {
+                    Interop.NtDll.ZeroMemory(ptr, (UIntPtr)(length * sizeof(char)));
+                    Win32Native.SysFreeString(ptr);
+                }
+
+                if (bufferPtr != null)
+                {
+                    _buffer.ReleasePointer();
+                }
+            }
+            return result;
+        }
+
         internal unsafe IntPtr MarshalToStringCore(bool globalAlloc, bool unicode)
         {
             int length = _decryptedLength;
index 3546994..1d7a153 100644 (file)
       <Member Name="ZeroFreeGlobalAllocAnsi(System.IntPtr)" />
       <Member Name="ZeroFreeGlobalAllocUnicode(System.IntPtr)" />
       <Member Name="ZeroFreeCoTaskMemUTF8(System.IntPtr)" />
+      <Member Name="SecureStringToCoTaskMemAnsi(System.Security.SecureString)" />
+      <Member Name="SecureStringToCoTaskMemUnicode(System.Security.SecureString)" />
+      <Member Name="SecureStringToGlobalAllocAnsi(System.Security.SecureString)" />
+      <Member Name="SecureStringToGlobalAllocUnicode(System.Security.SecureString)" />
+      <Member Name="SecureStringToBSTR(System.Security.SecureString)" />
     </Type>
     <Type Name="System.Runtime.InteropServices.MarshalAsAttribute">
       <Member MemberType="Field" Name="ArraySubType" />
index c212b2d..8b0c132 100644 (file)
@@ -2691,9 +2691,6 @@ namespace System.Runtime.InteropServices
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         internal static extern IntPtr GetFunctionPointerForDelegateInternal(Delegate d);
 
-#if FEATURE_LEGACYSURFACE
-
-#if FEATURE_COMINTEROP
         [System.Security.SecurityCritical]  // auto-generated_required
         public static IntPtr SecureStringToBSTR(SecureString s) {
             if( s == null) {
@@ -2701,9 +2698,12 @@ namespace System.Runtime.InteropServices
             }
             Contract.EndContractBlock();
             
-            return s.ToBSTR();
-        }
+#if FEATURE_COMINTEROP
+            return s.MarshalToBSTR();
+#else
+            throw new PlatformNotSupportedException();
 #endif
+        }
 
         [System.Security.SecurityCritical]  // auto-generated_required
         public static IntPtr SecureStringToCoTaskMemAnsi(SecureString s) {
@@ -2712,24 +2712,20 @@ namespace System.Runtime.InteropServices
             }
             Contract.EndContractBlock();
 
-            return s.ToAnsiStr(false);
+            return s.MarshalToString(globalAlloc: false, unicode: false);
         }
 
         [System.Security.SecurityCritical]  // auto-generated_required
         public static IntPtr SecureStringToCoTaskMemUnicode(SecureString s)
         {
-            if (s == null)
-            {
+            if( s == null) {
                 throw new ArgumentNullException(nameof(s));
             }
             Contract.EndContractBlock();
 
-            return s.ToUniStr(false);
+            return  s.MarshalToString(globalAlloc: false, unicode: true);
         }
 
-#endif // FEATURE_LEGACYSURFACE
-
-
 #if FEATURE_COMINTEROP
         [System.Security.SecurityCritical]  // auto-generated_required
         public static void ZeroFreeBSTR(IntPtr s)
@@ -2760,7 +2756,6 @@ namespace System.Runtime.InteropServices
             FreeCoTaskMem(s);
         }
 
-#if FEATURE_LEGACYSURFACE
         [System.Security.SecurityCritical]  // auto-generated_required
         public static IntPtr SecureStringToGlobalAllocAnsi(SecureString s) {
             if( s == null) {
@@ -2768,7 +2763,7 @@ namespace System.Runtime.InteropServices
             }
             Contract.EndContractBlock();
 
-            return s.ToAnsiStr(true);
+            return s.MarshalToString(globalAlloc: true, unicode: false);
         }
 
         [System.Security.SecurityCritical]  // auto-generated_required
@@ -2778,9 +2773,8 @@ namespace System.Runtime.InteropServices
             }
             Contract.EndContractBlock();
 
-            return s.ToUniStr(true);
+            return s.MarshalToString(globalAlloc: true, unicode: true);;
         }
-#endif // FEATURE_LEGACYSURFACE
 
         [System.Security.SecurityCritical]  // auto-generated_required
         public static void ZeroFreeGlobalAllocAnsi(IntPtr s) {