serverRoom/amt-sdk-20-0-0-1/HLAPI_Module/Src/Common/SecureStringExtensions.cs

192 lines
6.1 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace Common.Utils
{
/// <summary>
/// An extension class to handle SecureString conversion
/// </summary>
internal static class SecureStringExtensions
{
public static readonly Encoding ENCODING = Encoding.UTF8;
#region methods
/// <summary>
/// Convert the content of the SecureString as an array of bytes
/// </summary>
/// <param name="password"></param>
/// <returns> A Byte Array representation of a secure string </returns>
public static byte[] ConvertToByteArray(this SecureString password)
{
if (password == null)
{
throw new SecureStringConversionException("Cannot convert a null password");
}
IntPtr stringTempPass = IntPtr.Zero;
string convertedPass;
try
{
stringTempPass = Marshal.SecureStringToGlobalAllocUnicode(password);
convertedPass = Marshal.PtrToStringUni(stringTempPass);
if (convertedPass != null)
return ENCODING.GetBytes(convertedPass);
else
return null;
}
finally
{
Marshal.ZeroFreeGlobalAllocUnicode(stringTempPass);
}
}
/// <summary>
/// Convert the content of a byte array to a secure string
/// </summary>
/// <param name="arrayToConvert"></param>
/// <returns> The representation of the byte array in a secure string </returns>
public static SecureString ConvertByteArrayToSecureString(this byte[] arrayToConvert)
{
IntPtr stringPointer = IntPtr.Zero;
if (arrayToConvert.Length == 0)
throw new ArgumentException("Password is empty");
stringPointer = Marshal.StringToBSTR(ENCODING.GetString(arrayToConvert));
try
{
return ConvertToSecureString(Marshal.PtrToStringBSTR(stringPointer));
}
finally
{
Marshal.ZeroFreeBSTR(stringPointer);
GC.Collect();
}
}
/// <summary>
/// Convert a secure string to a char array
/// </summary>
/// <param name="password"></param>
/// <returns> A representation of the secure string in a char array </returns>
public static char[] ConvertToCharArray(this SecureString password)
{
char[] charArray = new char[password.Length];
IntPtr charPass = IntPtr.Zero;
try
{
charPass = Marshal.SecureStringToCoTaskMemUnicode(password);
Marshal.Copy(charPass, charArray, 0, password.Length);
return charArray;
}
finally
{
if (charPass != IntPtr.Zero)
{
Marshal.ZeroFreeGlobalAllocUnicode(charPass);
}
}
}
/// <summary>
/// Convert a SecureString to string. Used for compliancy with MSFT WINRM DLL
/// </summary>
/// <param name="password"></param>
/// <returns>a string represetation of a secure string </returns>
public static string ConvertToString(this SecureString password)
{
IntPtr stringPointer = IntPtr.Zero;
if (password == null)
throw new ArgumentNullException("Password is empty");
stringPointer = Marshal.SecureStringToBSTR(password);
try
{
return Marshal.PtrToStringBSTR(stringPointer);
}
finally
{
Marshal.ZeroFreeBSTR(stringPointer);
}
}
/// <summary>
/// Convert a String object to SecureString
/// </summary>
/// <param name="password"></param>
/// <returns>A secure string representation of a string object</returns>
public static SecureString ConvertToSecureString(this string password)
{
var securePass = new SecureString();
foreach (var c in password)
securePass.AppendChar(c);
securePass.MakeReadOnly();
return securePass;
}
/// <summary>
/// Compare the value of secure string object
/// </summary>
/// <param name="password"></param>
/// <param name="value"></param>
/// <returns>true/false according to the values equality</returns>
public static bool ValueEquals(this SecureString password, SecureString value)
{
IntPtr passBstr = IntPtr.Zero;
IntPtr valueBstr = IntPtr.Zero;
try
{
passBstr = Marshal.SecureStringToBSTR(password);
valueBstr = Marshal.SecureStringToBSTR(value);
int passLength = Marshal.ReadInt32(passBstr, -4);
int valueLength = Marshal.ReadInt32(valueBstr, -4);
if (passLength != valueLength)
return false;
for (int x = 0; x < passLength; ++x)
{
byte passByte = Marshal.ReadByte(passBstr, x);
byte valueByte = Marshal.ReadByte(valueBstr, x);
if (passByte != valueByte)
return false;
}
return true;
}
finally
{
if (passBstr != IntPtr.Zero)
Marshal.ZeroFreeBSTR(passBstr);
if (valueBstr != IntPtr.Zero)
Marshal.ZeroFreeBSTR(valueBstr);
}
}
}
public class SecureStringConversionException : Exception
{
public SecureStringConversionException()
{
}
public SecureStringConversionException(string message) : base(message)
{
}
public SecureStringConversionException(string message, Exception innerException) : base(message, innerException)
{
}
}
}
#endregion