You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

219 lines
7.2 KiB

namespace com.hitrust.Security.Cryptography
{
using com.hitrust.Security;
using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
public sealed class DataProtectionCryptoServiceProvider : IDisposable
{
private bool m_Disposed;
private byte[] m_OptionalEntropy;
public DataProtectionCryptoServiceProvider() : this(null)
{
}
public DataProtectionCryptoServiceProvider(byte[] optionalEntropy)
{
if (optionalEntropy != null)
{
this.m_OptionalEntropy = (byte[]) optionalEntropy.Clone();
}
this.m_Disposed = false;
}
public void Dispose()
{
if (this.m_OptionalEntropy != null)
{
Array.Clear(this.m_OptionalEntropy, 0, this.m_OptionalEntropy.Length);
}
this.m_Disposed = true;
}
~DataProtectionCryptoServiceProvider()
{
this.Dispose();
}
public byte[] ProtectData(ProtectionType type, byte[] data)
{
return this.ProtectData(type, data, this.Entropy);
}
public byte[] ProtectData(ProtectionType type, byte[] data, byte[] entropy)
{
if (data == null)
{
throw new ArgumentNullException();
}
return this.ProtectData(type, data, 0, data.Length, entropy);
}
public byte[] ProtectData(ProtectionType type, byte[] data, int offset, int size, byte[] entropy)
{
byte[] bytes;
if (this.m_Disposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
if (data == null)
{
throw new ArgumentNullException();
}
if (!(((offset >= 0) && ((offset + size) <= data.Length)) && Enum.IsDefined(typeof(ProtectionType), type)))
{
throw new ArgumentException();
}
DataBlob input = new DataBlob();
DataBlob entr = new DataBlob();
DataBlob output = new DataBlob();
try
{
input.cbData = size;
input.pbData = Marshal.AllocHGlobal(size);
Marshal.Copy(data, offset, input.pbData, size);
if (entropy == null)
{
entr.cbData = 0;
entr.pbData = IntPtr.Zero;
}
else
{
entr.cbData = entropy.Length;
entr.pbData = Marshal.AllocHGlobal(entr.cbData);
Marshal.Copy(entropy, 0, entr.pbData, entr.cbData);
}
output.cbData = 0;
output.pbData = IntPtr.Zero;
int flags = 0;
if (type == ProtectionType.LocalMachine)
{
flags |= 4;
}
if (!Environment.UserInteractive)
{
flags |= 1;
}
if ((SspiProvider.CryptProtectData(ref input, "", ref entr, IntPtr.Zero, IntPtr.Zero, flags, ref output) == 0) || (output.pbData == IntPtr.Zero))
{
throw new CryptographicException("The data could not be protected.");
}
byte[] ret = new byte[output.cbData];
Marshal.Copy(output.pbData, ret, 0, output.cbData);
bytes = ret;
}
finally
{
if (input.pbData != IntPtr.Zero)
{
Marshal.FreeHGlobal(input.pbData);
}
if (entr.pbData != IntPtr.Zero)
{
Marshal.FreeHGlobal(entr.pbData);
}
if (output.pbData != IntPtr.Zero)
{
Marshal.FreeHGlobal(output.pbData);
}
}
return bytes;
}
public byte[] UnprotectData(byte[] data)
{
return this.UnprotectData(data, this.Entropy);
}
public byte[] UnprotectData(byte[] data, byte[] entropy)
{
if (data == null)
{
throw new ArgumentNullException();
}
return this.UnprotectData(data, 0, data.Length, entropy);
}
public byte[] UnprotectData(byte[] data, int offset, int size, byte[] entropy)
{
byte[] a;
if (this.m_Disposed)
{
throw new ObjectDisposedException(base.GetType().FullName);
}
if (data == null)
{
throw new ArgumentNullException();
}
if ((offset < 0) || ((offset + size) > data.Length))
{
throw new ArgumentException();
}
DataBlob input = new DataBlob();
DataBlob entr = new DataBlob();
DataBlob output = new DataBlob();
try
{
input.cbData = size;
input.pbData = Marshal.AllocHGlobal(size);
Marshal.Copy(data, offset, input.pbData, size);
if (entropy == null)
{
entr.cbData = 0;
entr.pbData = IntPtr.Zero;
}
else
{
entr.cbData = entropy.Length;
entr.pbData = Marshal.AllocHGlobal(entr.cbData);
Marshal.Copy(entropy, 0, entr.pbData, entr.cbData);
}
output.cbData = 0;
output.pbData = IntPtr.Zero;
int flags = 0;
if (!Environment.UserInteractive)
{
flags |= 1;
}
if ((SspiProvider.CryptUnprotectData(ref input, IntPtr.Zero, ref entr, IntPtr.Zero, IntPtr.Zero, flags, ref output) == 0) || (output.pbData == IntPtr.Zero))
{
throw new CryptographicException("The data could not be unprotected.");
}
byte[] ret = new byte[output.cbData];
Marshal.Copy(output.pbData, ret, 0, output.cbData);
a = ret;
}
finally
{
if (input.pbData != IntPtr.Zero)
{
Marshal.FreeHGlobal(input.pbData);
}
if (entr.pbData != IntPtr.Zero)
{
Marshal.FreeHGlobal(entr.pbData);
}
if (output.pbData != IntPtr.Zero)
{
Marshal.FreeHGlobal(output.pbData);
}
}
return a;
}
public byte[] Entropy
{
get
{
return this.m_OptionalEntropy;
}
set
{
this.m_OptionalEntropy = value;
}
}
}
}