예제 #1
0
        // -----------------------------
        // ---- PAL layer ends here ----
        // -----------------------------

        private void EnsureCapacity(int capacity)
        {
            // Make sure the requested capacity doesn't exceed SecureString's defined limit
            if (capacity > MaxLength)
            {
                throw new ArgumentOutOfRangeException("capacity", SR.ArgumentOutOfRange_Capacity);
            }

            // If we already have enough space allocated, we're done
            if (_buffer != null && (capacity * sizeof(char)) <= (int)_buffer.ByteLength)
            {
                return;
            }

            // We need more space, so allocate a new buffer, copy all our data into it,
            // and then swap the new for the old.
            ProtectedBuffer newBuffer = ProtectedBuffer.Allocate(capacity * sizeof(char));

            if (_buffer != null)
            {
                using (_buffer.Unprotect())
                    ProtectedBuffer.Copy(_buffer, newBuffer, _buffer.ByteLength);
                newBuffer.Protect();
                _buffer.Dispose();
            }
            _buffer = newBuffer;
        }
예제 #2
0
            internal static unsafe void Copy(ProtectedBuffer source, ProtectedBuffer destination, ulong bytesLength)
            {
                if (bytesLength == 0)
                {
                    return;
                }

                byte *srcPtr = null, dstPtr = null;

                try
                {
                    source.AcquirePointer(ref srcPtr);
                    destination.AcquirePointer(ref dstPtr);
                    Buffer.MemoryCopy(srcPtr, dstPtr, destination.ByteLength, bytesLength);
                }
                finally
                {
                    if (dstPtr != null)
                    {
                        destination.ReleasePointer();
                    }
                    if (srcPtr != null)
                    {
                        source.ReleasePointer();
                    }
                }
            }
예제 #3
0
 [System.Security.SecuritySafeCritical]  // auto-generated
 private void DisposeCore()
 {
     if (_buffer != null && !_buffer.IsInvalid)
     {
         _buffer.Dispose();
         _buffer = null;
     }
 }
예제 #4
0
 [System.Security.SecuritySafeCritical]  // auto-generated
 private void DisposeCore()
 {
     if (_buffer != null && !_buffer.IsInvalid)
     {
         _buffer.Dispose();
         _buffer = null;
     }
 }
예제 #5
0
            internal static ProtectedBuffer Allocate(int bytes)
            {
                Debug.Assert(bytes >= 0);

                // Round the number of bytes up to the next page size boundary.  mmap
                // is going to allocate pages, anyway, and we lock/protect entire pages,
                // so we might as well benefit from being able to use all of that space,
                // rather than allocating it and having it be unusable.  As a SecureString
                // grows, this will significantly help in avoiding unnecessary recreations
                // of the buffer.
                Debug.Assert(s_pageSize > 0);
                ulong nativeBytes = RoundUpToPageSize(bytes);

                Debug.Assert((long)nativeBytes % s_pageSize == 0);

                ProtectedBuffer buffer = new ProtectedBuffer();
                IntPtr          ptr    = IntPtr.Zero;

                try
                {
                    // Allocate the page(s) for the buffer.
                    ptr = Interop.Sys.MMap(
                        IntPtr.Zero,
                        nativeBytes,
                        Interop.Sys.MemoryMappedProtections.PROT_READ | Interop.Sys.MemoryMappedProtections.PROT_WRITE,
                        Interop.Sys.MemoryMappedFlags.MAP_ANONYMOUS | Interop.Sys.MemoryMappedFlags.MAP_PRIVATE, 0,
                        0);
                    if (ptr == IntPtr.Zero) // note that shim uses null pointer, not non-null MAP_FAILED sentinel
                    {
                        throw CreateExceptionFromErrno();
                    }

                    // Lock the pages into memory to minimize the chances that the pages get
                    // swapped out, making the contents available on disk.
                    if (Interop.Sys.MLock(ptr, nativeBytes) != 0)
                    {
                        throw CreateExceptionFromErrno();
                    }
                }
                catch
                {
                    // Something failed; release the allocation
                    if (ptr != IntPtr.Zero)
                    {
                        Interop.Sys.MUnmap(ptr, nativeBytes); // ignore any errors
                    }
                    throw;
                }

                // The memory was allocated; initialize the buffer with it.
                buffer.SetHandle(ptr);
                buffer.Initialize((ulong)bytes);
                return(buffer);
            }
예제 #6
0
        [System.Security.SecurityCritical]  // auto-generated
        internal unsafe IntPtr ToUniStrCore()
        {
            int length = _decryptedLength;

            byte * bufferPtr = null;
            IntPtr stringPtr = IntPtr.Zero, result = IntPtr.Zero;

            try
            {
                // Allocate space for the string to be returned, including space for a null terminator
                if ((stringPtr = Marshal.AllocCoTaskMem((length + 1) * sizeof(char))) == IntPtr.Zero)
                {
                    throw new OutOfMemoryException();
                }

                _buffer.AcquirePointer(ref bufferPtr);

                // Copy all of our data into it
                using (_buffer.Unprotect())
                    Buffer.MemoryCopy(
                        source: bufferPtr,
                        destination: (byte *)stringPtr.ToPointer(),
                        destinationSizeInBytes: ((length + 1) * sizeof(char)),
                        sourceBytesToCopy: length * sizeof(char));

                // Add the null termination
                *(length + (char *)stringPtr.ToPointer()) = '\0';

                // Finally store the string pointer into our result.  We maintain
                // a separate result variable to make clean up in the finally easier.
                result = stringPtr;
            }
            finally
            {
                // If there was a failure, such that result isn't initialized,
                // release the string if we had one.
                if (stringPtr != IntPtr.Zero && result == IntPtr.Zero)
                {
                    ProtectedBuffer.ZeroMemory((byte *)stringPtr, (ulong)(length * sizeof(char)));
                    Marshal.FreeCoTaskMem(stringPtr);
                }

                if (bufferPtr != null)
                {
                    _buffer.ReleasePointer();
                }
            }

            return(result);
        }
예제 #7
0
        [System.Security.SecurityCritical]  // auto-generated
        internal unsafe SecureString(SecureString str)
        {
            // Allocate enough space to store the provided string
            EnsureCapacity(str._decryptedLength);
            _decryptedLength = str._decryptedLength;

            // Copy the string into the newly allocated space
            if (_decryptedLength > 0)
            {
                using (str._buffer.Unprotect())
                    ProtectedBuffer.Copy(str._buffer, _buffer, (ulong)(str._decryptedLength * sizeof(char)));
            }

            // Protect the buffer
            _buffer.Protect();
        }
예제 #8
0
 internal ProtectOnDispose(ProtectedBuffer buffer)
 {
     Debug.Assert(buffer != null);
     _buffer = buffer;
 }
예제 #9
0
            internal static unsafe void Copy(ProtectedBuffer source, ProtectedBuffer destination, ulong bytesLength)
            {
                if (bytesLength == 0)
                    return;

                byte* srcPtr = null, dstPtr = null;
                try
                {
                    source.AcquirePointer(ref srcPtr);
                    destination.AcquirePointer(ref dstPtr);
                    Buffer.MemoryCopy(srcPtr, dstPtr, destination.ByteLength, bytesLength);
                }
                finally
                {
                    if (dstPtr != null)
                        destination.ReleasePointer();
                    if (srcPtr != null)
                        source.ReleasePointer();
                }
            }
예제 #10
0
 internal ProtectOnDispose(ProtectedBuffer buffer)
 {
     Debug.Assert(buffer != null);
     _buffer = buffer;
 }
예제 #11
0
            internal static ProtectedBuffer Allocate(int bytes)
            {
                Debug.Assert(bytes >= 0);

                // Round the number of bytes up to the next page size boundary.  mmap
                // is going to allocate pages, anyway, and we lock/protect entire pages,
                // so we might as well benefit from being able to use all of that space,
                // rather than allocating it and having it be unusable.  As a SecureString
                // grows, this will significantly help in avoiding unnecessary recreations
                // of the buffer.
                Debug.Assert(s_pageSize > 0);
                ulong nativeBytes = RoundUpToPageSize(bytes);
                Debug.Assert((long)nativeBytes % s_pageSize == 0);

                ProtectedBuffer buffer = new ProtectedBuffer();
                IntPtr ptr = IntPtr.Zero;
                try
                {
                    // Allocate the page(s) for the buffer.
                    ptr = Interop.Sys.MMap(
                        IntPtr.Zero,
                        nativeBytes,
                        Interop.Sys.MemoryMappedProtections.PROT_READ | Interop.Sys.MemoryMappedProtections.PROT_WRITE,
                        Interop.Sys.MemoryMappedFlags.MAP_ANONYMOUS | Interop.Sys.MemoryMappedFlags.MAP_PRIVATE, 0,
                        0);
                    if (ptr == IntPtr.Zero) // note that shim uses null pointer, not non-null MAP_FAILED sentinel
                        throw CreateExceptionFromErrno();

                    // Lock the pages into memory to minimize the chances that the pages get
                    // swapped out, making the contents available on disk.
                    if (Interop.Sys.MLock(ptr, nativeBytes) != 0)
                        throw CreateExceptionFromErrno();
                }
                catch
                {
                    // Something failed; release the allocation
                    if (ptr != IntPtr.Zero)
                        Interop.Sys.MUnmap(ptr, nativeBytes); // ignore any errors
                    throw;
                }

                // The memory was allocated; initialize the buffer with it.
                buffer.SetHandle(ptr);
                buffer.Initialize((ulong)bytes);
                return buffer;
            }
예제 #12
0
        // -----------------------------
        // ---- PAL layer ends here ----
        // -----------------------------

        private void EnsureCapacity(int capacity)
        {
            // Make sure the requested capacity doesn't exceed SecureString's defined limit
            if (capacity > MaxLength)
                throw new ArgumentOutOfRangeException("capacity", SR.ArgumentOutOfRange_Capacity);

            // If we already have enough space allocated, we're done
            if (_buffer != null && (capacity * sizeof(char)) <= (int)_buffer.ByteLength)
                return;

            // We need more space, so allocate a new buffer, copy all our data into it,
            // and then swap the new for the old.
            ProtectedBuffer newBuffer = ProtectedBuffer.Allocate(capacity * sizeof(char));
            if (_buffer != null)
            {
                using (_buffer.Unprotect())
                    ProtectedBuffer.Copy(_buffer, newBuffer, _buffer.ByteLength);
                newBuffer.Protect();
                _buffer.Dispose();
            }
            _buffer = newBuffer;
        }