360 lines
13 KiB
C#
360 lines
13 KiB
C#
using System;
|
|
using System.Runtime.ConstrainedExecution;
|
|
|
|
namespace System.Security
|
|
{
|
|
/// <summary>Represents text that should be kept confidential. The text is encrypted for privacy when being used, and deleted from computer memory when no longer needed. This class cannot be inherited.</summary>
|
|
// Token: 0x020005C9 RID: 1481
|
|
[MonoTODO("work in progress - encryption is missing")]
|
|
public sealed class SecureString : CriticalFinalizerObject, IDisposable
|
|
{
|
|
/// <summary>Initializes a new instance of the <see cref="T:System.Security.SecureString" /> class.</summary>
|
|
/// <exception cref="T:System.Security.Cryptography.CryptographicException">An error occurred while encrypting or decrypting the value of this instance.</exception>
|
|
/// <exception cref="T:System.NotSupportedException">This operation is not supported on this platform.</exception>
|
|
// Token: 0x060035FF RID: 13823 RVA: 0x000B8868 File Offset: 0x000B6A68
|
|
public SecureString()
|
|
{
|
|
this.Alloc(8, false);
|
|
}
|
|
|
|
/// <summary>Initializes a new instance of the <see cref="T:System.Security.SecureString" /> class from a subarray of <see cref="T:System.Char" /> objects.</summary>
|
|
/// <param name="value">A pointer to an array of <see cref="T:System.Char" /> objects.</param>
|
|
/// <param name="length">The number of elements of <paramref name="value" /> to include in the new instance.</param>
|
|
/// <exception cref="T:System.ArgumentNullException">
|
|
/// <paramref name="value" /> is null.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
|
/// <paramref name="length" /> is less than zero or greater than 65536.</exception>
|
|
/// <exception cref="T:System.Security.Cryptography.CryptographicException">An error occurred while encrypting or decrypting the value of this secure string.</exception>
|
|
/// <exception cref="T:System.NotSupportedException">This operation is not supported on this platform.</exception>
|
|
// Token: 0x06003600 RID: 13824 RVA: 0x000B8878 File Offset: 0x000B6A78
|
|
[CLSCompliant(false)]
|
|
public unsafe SecureString(char* value, int length)
|
|
{
|
|
if (value == null)
|
|
{
|
|
throw new ArgumentNullException("value");
|
|
}
|
|
if (length < 0 || length > 65536)
|
|
{
|
|
throw new ArgumentOutOfRangeException("length", "< 0 || > 65536");
|
|
}
|
|
this.length = length;
|
|
this.Alloc(length, false);
|
|
int num = 0;
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
char c = *(value++);
|
|
this.data[num++] = (byte)(c >> 8);
|
|
this.data[num++] = (byte)c;
|
|
}
|
|
this.Encrypt();
|
|
}
|
|
|
|
/// <summary>Gets the number of characters in the current secure string.</summary>
|
|
/// <returns>The number of <see cref="T:System.Char" /> objects in this secure string.</returns>
|
|
/// <exception cref="T:System.ObjectDisposedException">This secure string has already been disposed.</exception>
|
|
// Token: 0x17000A8F RID: 2703
|
|
// (get) Token: 0x06003602 RID: 13826 RVA: 0x000B8914 File Offset: 0x000B6B14
|
|
public int Length
|
|
{
|
|
get
|
|
{
|
|
if (this.disposed)
|
|
{
|
|
throw new ObjectDisposedException("SecureString");
|
|
}
|
|
return this.length;
|
|
}
|
|
}
|
|
|
|
/// <summary>Appends a character to the end of the current secure string.</summary>
|
|
/// <param name="c">A character to append to this secure string.</param>
|
|
/// <exception cref="T:System.ObjectDisposedException">This secure string has already been disposed.</exception>
|
|
/// <exception cref="T:System.InvalidOperationException">This secure string is read-only.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">Performing this operation would make the length of this secure string greater than 65536 characters.</exception>
|
|
/// <exception cref="T:System.Security.Cryptography.CryptographicException">An error occurred while encrypting or decrypting the value of this secure string.</exception>
|
|
// Token: 0x06003603 RID: 13827 RVA: 0x000B8934 File Offset: 0x000B6B34
|
|
public void AppendChar(char c)
|
|
{
|
|
if (this.disposed)
|
|
{
|
|
throw new ObjectDisposedException("SecureString");
|
|
}
|
|
if (this.read_only)
|
|
{
|
|
throw new InvalidOperationException(Locale.GetText("SecureString is read-only."));
|
|
}
|
|
if (this.length == 65536)
|
|
{
|
|
throw new ArgumentOutOfRangeException("length", "> 65536");
|
|
}
|
|
try
|
|
{
|
|
this.Decrypt();
|
|
int num = this.length * 2;
|
|
this.Alloc(++this.length, true);
|
|
this.data[num++] = (byte)(c >> 8);
|
|
this.data[num++] = (byte)c;
|
|
}
|
|
finally
|
|
{
|
|
this.Encrypt();
|
|
}
|
|
}
|
|
|
|
/// <summary>Deletes the value of the current secure string.</summary>
|
|
/// <exception cref="T:System.ObjectDisposedException">This secure string has already been disposed.</exception>
|
|
/// <exception cref="T:System.InvalidOperationException">This secure string is read-only.</exception>
|
|
// Token: 0x06003604 RID: 13828 RVA: 0x000B8A00 File Offset: 0x000B6C00
|
|
public void Clear()
|
|
{
|
|
if (this.disposed)
|
|
{
|
|
throw new ObjectDisposedException("SecureString");
|
|
}
|
|
if (this.read_only)
|
|
{
|
|
throw new InvalidOperationException(Locale.GetText("SecureString is read-only."));
|
|
}
|
|
Array.Clear(this.data, 0, this.data.Length);
|
|
this.length = 0;
|
|
}
|
|
|
|
/// <summary>Creates a copy of the current secure string.</summary>
|
|
/// <returns>A duplicate of this secure string.</returns>
|
|
/// <exception cref="T:System.ObjectDisposedException">This secure string has already been disposed.</exception>
|
|
/// <exception cref="T:System.Security.Cryptography.CryptographicException">An error occurred while encrypting or decrypting the value of this secure string.</exception>
|
|
// Token: 0x06003605 RID: 13829 RVA: 0x000B8A5C File Offset: 0x000B6C5C
|
|
public SecureString Copy()
|
|
{
|
|
return new SecureString
|
|
{
|
|
data = (byte[])this.data.Clone(),
|
|
length = this.length
|
|
};
|
|
}
|
|
|
|
/// <summary>Releases all resources used by the current <see cref="T:System.Security.SecureString" /> object.</summary>
|
|
// Token: 0x06003606 RID: 13830 RVA: 0x000B8A94 File Offset: 0x000B6C94
|
|
public void Dispose()
|
|
{
|
|
this.disposed = true;
|
|
if (this.data != null)
|
|
{
|
|
Array.Clear(this.data, 0, this.data.Length);
|
|
this.data = null;
|
|
}
|
|
this.length = 0;
|
|
}
|
|
|
|
/// <summary>Inserts a character in this secure string at the specified index position.</summary>
|
|
/// <param name="index">The index position where parameter <paramref name="c" /> is inserted.</param>
|
|
/// <param name="c">The character to insert.</param>
|
|
/// <exception cref="T:System.ObjectDisposedException">This secure string has already been disposed.</exception>
|
|
/// <exception cref="T:System.InvalidOperationException">This secure string is read-only.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
|
/// <paramref name="index" /> is less than zero, or greater than the length of this secure string.-or-Performing this operation would make the length of this secure string greater than 65536 characters.</exception>
|
|
/// <exception cref="T:System.Security.Cryptography.CryptographicException">An error occurred while encrypting or decrypting the value of this secure string.</exception>
|
|
// Token: 0x06003607 RID: 13831 RVA: 0x000B8AD8 File Offset: 0x000B6CD8
|
|
public void InsertAt(int index, char c)
|
|
{
|
|
if (this.disposed)
|
|
{
|
|
throw new ObjectDisposedException("SecureString");
|
|
}
|
|
if (this.read_only)
|
|
{
|
|
throw new InvalidOperationException(Locale.GetText("SecureString is read-only."));
|
|
}
|
|
if (index < 0 || index > this.length)
|
|
{
|
|
throw new ArgumentOutOfRangeException("index", "< 0 || > length");
|
|
}
|
|
if (this.length >= 65536)
|
|
{
|
|
string text = Locale.GetText("Maximum string size is '{0}'.", new object[] { 65536 });
|
|
throw new ArgumentOutOfRangeException("index", text);
|
|
}
|
|
try
|
|
{
|
|
this.Decrypt();
|
|
this.Alloc(++this.length, true);
|
|
int num = index * 2;
|
|
Buffer.BlockCopy(this.data, num, this.data, num + 2, this.data.Length - num - 2);
|
|
this.data[num++] = (byte)(c >> 8);
|
|
this.data[num] = (byte)c;
|
|
}
|
|
finally
|
|
{
|
|
this.Encrypt();
|
|
}
|
|
}
|
|
|
|
/// <summary>Indicates whether this secure string is marked read-only.</summary>
|
|
/// <returns>true if this secure string is marked read-only; otherwise, false.</returns>
|
|
/// <exception cref="T:System.ObjectDisposedException">This secure string has already been disposed.</exception>
|
|
// Token: 0x06003608 RID: 13832 RVA: 0x000B8BF8 File Offset: 0x000B6DF8
|
|
public bool IsReadOnly()
|
|
{
|
|
if (this.disposed)
|
|
{
|
|
throw new ObjectDisposedException("SecureString");
|
|
}
|
|
return this.read_only;
|
|
}
|
|
|
|
/// <summary>Makes the text value of this secure string read-only. </summary>
|
|
/// <exception cref="T:System.ObjectDisposedException">This secure string has already been disposed.</exception>
|
|
// Token: 0x06003609 RID: 13833 RVA: 0x000B8C18 File Offset: 0x000B6E18
|
|
public void MakeReadOnly()
|
|
{
|
|
this.read_only = true;
|
|
}
|
|
|
|
/// <summary>Removes the character at the specified index position from this secure string.</summary>
|
|
/// <param name="index">The index position of a character in this secure string.</param>
|
|
/// <exception cref="T:System.ObjectDisposedException">This secure string has already been disposed.</exception>
|
|
/// <exception cref="T:System.InvalidOperationException">This secure string is read-only.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
|
/// <paramref name="index" /> is less than zero, or greater than or equal to the length of this secure string.</exception>
|
|
/// <exception cref="T:System.Security.Cryptography.CryptographicException">An error occurred while encrypting or decrypting the value of this secure string.</exception>
|
|
// Token: 0x0600360A RID: 13834 RVA: 0x000B8C24 File Offset: 0x000B6E24
|
|
public void RemoveAt(int index)
|
|
{
|
|
if (this.disposed)
|
|
{
|
|
throw new ObjectDisposedException("SecureString");
|
|
}
|
|
if (this.read_only)
|
|
{
|
|
throw new InvalidOperationException(Locale.GetText("SecureString is read-only."));
|
|
}
|
|
if (index < 0 || index >= this.length)
|
|
{
|
|
throw new ArgumentOutOfRangeException("index", "< 0 || > length");
|
|
}
|
|
try
|
|
{
|
|
this.Decrypt();
|
|
Buffer.BlockCopy(this.data, index + 1, this.data, index, this.data.Length - index - 1);
|
|
this.Alloc(--this.length, true);
|
|
}
|
|
finally
|
|
{
|
|
this.Encrypt();
|
|
}
|
|
}
|
|
|
|
/// <summary>Replaces the existing character at the specified index position with another character.</summary>
|
|
/// <param name="index">The index position of an existing character in this secure string</param>
|
|
/// <param name="c">A character that replaces the existing character.</param>
|
|
/// <exception cref="T:System.ObjectDisposedException">This secure string has already been disposed.</exception>
|
|
/// <exception cref="T:System.InvalidOperationException">This secure string is read-only.</exception>
|
|
/// <exception cref="T:System.ArgumentOutOfRangeException">
|
|
/// <paramref name="index" /> is less than zero, or greater than or equal to the length of this secure string.</exception>
|
|
/// <exception cref="T:System.Security.Cryptography.CryptographicException">An error occurred while encrypting or decrypting the value of this secure string.</exception>
|
|
// Token: 0x0600360B RID: 13835 RVA: 0x000B8CEC File Offset: 0x000B6EEC
|
|
public void SetAt(int index, char c)
|
|
{
|
|
if (this.disposed)
|
|
{
|
|
throw new ObjectDisposedException("SecureString");
|
|
}
|
|
if (this.read_only)
|
|
{
|
|
throw new InvalidOperationException(Locale.GetText("SecureString is read-only."));
|
|
}
|
|
if (index < 0 || index >= this.length)
|
|
{
|
|
throw new ArgumentOutOfRangeException("index", "< 0 || > length");
|
|
}
|
|
try
|
|
{
|
|
this.Decrypt();
|
|
int num = index * 2;
|
|
this.data[num++] = (byte)(c >> 8);
|
|
this.data[num] = (byte)c;
|
|
}
|
|
finally
|
|
{
|
|
this.Encrypt();
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600360C RID: 13836 RVA: 0x000B8D9C File Offset: 0x000B6F9C
|
|
private void Encrypt()
|
|
{
|
|
if (this.data == null || this.data.Length > 0)
|
|
{
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600360D RID: 13837 RVA: 0x000B8DB8 File Offset: 0x000B6FB8
|
|
private void Decrypt()
|
|
{
|
|
if (this.data == null || this.data.Length > 0)
|
|
{
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600360E RID: 13838 RVA: 0x000B8DD4 File Offset: 0x000B6FD4
|
|
private void Alloc(int length, bool realloc)
|
|
{
|
|
if (length < 0 || length > 65536)
|
|
{
|
|
throw new ArgumentOutOfRangeException("length", "< 0 || > 65536");
|
|
}
|
|
int num = (length >> 3) + (((length & 7) != 0) ? 1 : 0) << 4;
|
|
if (realloc && this.data != null && num == this.data.Length)
|
|
{
|
|
return;
|
|
}
|
|
if (realloc)
|
|
{
|
|
byte[] array = new byte[num];
|
|
Array.Copy(this.data, 0, array, 0, Math.Min(this.data.Length, array.Length));
|
|
Array.Clear(this.data, 0, this.data.Length);
|
|
this.data = array;
|
|
}
|
|
else
|
|
{
|
|
this.data = new byte[num];
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600360F RID: 13839 RVA: 0x000B8E90 File Offset: 0x000B7090
|
|
internal byte[] GetBuffer()
|
|
{
|
|
byte[] array = new byte[this.length << 1];
|
|
try
|
|
{
|
|
this.Decrypt();
|
|
Buffer.BlockCopy(this.data, 0, array, 0, array.Length);
|
|
}
|
|
finally
|
|
{
|
|
this.Encrypt();
|
|
}
|
|
return array;
|
|
}
|
|
|
|
// Token: 0x0400161D RID: 5661
|
|
private const int BlockSize = 16;
|
|
|
|
// Token: 0x0400161E RID: 5662
|
|
private const int MaxSize = 65536;
|
|
|
|
// Token: 0x0400161F RID: 5663
|
|
private int length;
|
|
|
|
// Token: 0x04001620 RID: 5664
|
|
private bool disposed;
|
|
|
|
// Token: 0x04001621 RID: 5665
|
|
private bool read_only;
|
|
|
|
// Token: 0x04001622 RID: 5666
|
|
private byte[] data;
|
|
}
|
|
}
|