summaryrefslogtreecommitdiff
path: root/src/mscorlib/shared/System/Security/SecureString.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/shared/System/Security/SecureString.cs')
-rw-r--r--src/mscorlib/shared/System/Security/SecureString.cs189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/mscorlib/shared/System/Security/SecureString.cs b/src/mscorlib/shared/System/Security/SecureString.cs
new file mode 100644
index 0000000000..9059f90e60
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SecureString.cs
@@ -0,0 +1,189 @@
+// 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.
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace System.Security
+{
+ public sealed partial class SecureString : IDisposable
+ {
+ private const int MaxLength = 65536;
+ private readonly object _methodLock = new object();
+ private bool _readOnly;
+ private int _decryptedLength;
+
+ public unsafe SecureString()
+ {
+ InitializeSecureString(null, 0);
+ }
+
+ [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), SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+ if (length > MaxLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Length);
+ }
+
+ InitializeSecureString(value, length);
+ }
+
+ public int Length
+ {
+ get
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ return _decryptedLength;
+ }
+ }
+ }
+
+ public void AppendChar(char c)
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ EnsureNotReadOnly();
+ AppendCharCore(c);
+ }
+ }
+
+ // clears the current contents. Only available if writable
+ public void Clear()
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ EnsureNotReadOnly();
+ ClearCore();
+ }
+ }
+
+ // Do a deep-copy of the SecureString
+ public SecureString Copy()
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ return new SecureString(this);
+ }
+ }
+
+ public void Dispose()
+ {
+ lock (_methodLock)
+ {
+ DisposeCore();
+ }
+ }
+
+ public void InsertAt(int index, char c)
+ {
+ lock (_methodLock)
+ {
+ if (index < 0 || index > _decryptedLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexString);
+ }
+
+ EnsureNotDisposed();
+ EnsureNotReadOnly();
+
+ InsertAtCore(index, c);
+ }
+ }
+
+ public bool IsReadOnly()
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ return _readOnly;
+ }
+ }
+
+ public void MakeReadOnly()
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ _readOnly = true;
+ }
+ }
+
+ public void RemoveAt(int index)
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ EnsureNotReadOnly();
+
+ if (index < 0 || index >= _decryptedLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexString);
+ }
+
+ RemoveAtCore(index);
+ }
+ }
+
+ public void SetAt(int index, char c)
+ {
+ lock (_methodLock)
+ {
+ if (index < 0 || index >= _decryptedLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexString);
+ }
+ Debug.Assert(index <= Int32.MaxValue / sizeof(char));
+
+ EnsureNotDisposed();
+ EnsureNotReadOnly();
+
+ SetAtCore(index, c);
+ }
+ }
+
+ private void EnsureNotReadOnly()
+ {
+ if (_readOnly)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
+ }
+
+ internal unsafe IntPtr MarshalToString(bool globalAlloc, bool unicode)
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ return MarshalToStringCore(globalAlloc, unicode);
+ }
+ }
+
+ private static void MarshalFree(IntPtr ptr, bool globalAlloc)
+ {
+ if (globalAlloc)
+ {
+ Marshal.FreeHGlobal(ptr);
+ }
+ else
+ {
+ Marshal.FreeCoTaskMem(ptr);
+ }
+ }
+ }
+}