namespace com.hitrust.b2b.Security.Cryptography
|
|
{
|
|
using com.hitrust.b2b.Security;
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security.Cryptography;
|
|
|
|
public sealed class RC4CryptoServiceProvider : RC4
|
|
{
|
|
private bool m_Disposed;
|
|
private ARCFourManaged m_Managed;
|
|
private int m_MaxLen;
|
|
private int m_MinLen;
|
|
private int m_Provider = 0;
|
|
|
|
public RC4CryptoServiceProvider()
|
|
{
|
|
if ((SspiProvider.CryptAcquireContext(ref this.m_Provider, IntPtr.Zero, null, 1, 0) == 0) && (Marshal.GetLastWin32Error() == -2146893802))
|
|
{
|
|
SspiProvider.CryptAcquireContext(ref this.m_Provider, IntPtr.Zero, null, 1, 8);
|
|
}
|
|
if (this.m_Provider != 0)
|
|
{
|
|
int dwFlags = 1;
|
|
bool flag = false;
|
|
IntPtr pbData = Marshal.AllocHGlobal(100);
|
|
do
|
|
{
|
|
int pdwDataLen = 100;
|
|
if (SspiProvider.CryptGetProvParam(this.m_Provider, 0x16, pbData, ref pdwDataLen, dwFlags) == 0)
|
|
{
|
|
break;
|
|
}
|
|
dwFlags = 0;
|
|
com.hitrust.b2b.Security.PROV_ENUMALGS_EX prov_enumalgs_ex = (com.hitrust.b2b.Security.PROV_ENUMALGS_EX) Marshal.PtrToStructure(pbData, typeof(com.hitrust.b2b.Security.PROV_ENUMALGS_EX));
|
|
if (prov_enumalgs_ex.aiAlgid == 0x6801)
|
|
{
|
|
flag = true;
|
|
this.m_MinLen = prov_enumalgs_ex.dwMinLen;
|
|
this.m_MaxLen = prov_enumalgs_ex.dwMaxLen;
|
|
}
|
|
}
|
|
while (!flag);
|
|
Marshal.FreeHGlobal(pbData);
|
|
if (!flag)
|
|
{
|
|
SspiProvider.CryptReleaseContext(this.m_Provider, 0);
|
|
this.m_Provider = 0;
|
|
}
|
|
}
|
|
this.m_Managed = new ARCFourManaged();
|
|
}
|
|
|
|
private bool CanUseUnmanaged(int keySize)
|
|
{
|
|
return (((this.m_Provider != 0) && (keySize >= this.m_MinLen)) && (keySize <= this.m_MaxLen));
|
|
}
|
|
|
|
public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
|
|
{
|
|
if (this.m_Disposed)
|
|
{
|
|
throw new ObjectDisposedException(base.GetType().FullName);
|
|
}
|
|
if (rgbKey == null)
|
|
{
|
|
throw new ArgumentNullException("Key is a null reference.");
|
|
}
|
|
if ((rgbKey.Length == 0) || (rgbKey.Length > 0x100))
|
|
{
|
|
throw new CryptographicException("Invalid Key.");
|
|
}
|
|
if ((rgbIV != null) && (rgbIV.Length > 1))
|
|
{
|
|
throw new CryptographicException("Invalid Initialization Vector.");
|
|
}
|
|
try
|
|
{
|
|
if (this.CanUseUnmanaged(rgbKey.Length * 8))
|
|
{
|
|
return new RC4UnmanagedTransform(rgbKey);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
return this.m_Managed.CreateDecryptor(rgbKey, rgbIV);
|
|
}
|
|
|
|
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
|
|
{
|
|
return this.CreateDecryptor(rgbKey, rgbIV);
|
|
}
|
|
|
|
private void CurrentDispose()
|
|
{
|
|
if (!this.m_Disposed)
|
|
{
|
|
this.m_Disposed = true;
|
|
if (this.m_Managed != null)
|
|
{
|
|
this.m_Managed.Clear();
|
|
this.m_Managed = null;
|
|
}
|
|
if (this.m_Provider != 0)
|
|
{
|
|
SspiProvider.CryptReleaseContext(this.m_Provider, 0);
|
|
this.m_Provider = 0;
|
|
}
|
|
try
|
|
{
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
~RC4CryptoServiceProvider()
|
|
{
|
|
this.CurrentDispose();
|
|
}
|
|
|
|
public override void GenerateIV()
|
|
{
|
|
this.m_Managed.GenerateIV();
|
|
}
|
|
|
|
public override void GenerateKey()
|
|
{
|
|
this.m_Managed.GenerateKey();
|
|
}
|
|
|
|
public override int BlockSize
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.BlockSize;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.BlockSize = value;
|
|
}
|
|
}
|
|
|
|
public override int FeedbackSize
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.FeedbackSize;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.FeedbackSize = value;
|
|
}
|
|
}
|
|
|
|
public override byte[] IV
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.IV;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.IV = value;
|
|
}
|
|
}
|
|
|
|
public override byte[] Key
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.Key;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.Key = value;
|
|
}
|
|
}
|
|
|
|
public override int KeySize
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.KeySize;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.KeySize = value;
|
|
}
|
|
}
|
|
|
|
public override KeySizes[] LegalBlockSizes
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.LegalBlockSizes;
|
|
}
|
|
}
|
|
|
|
public override KeySizes[] LegalKeySizes
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.LegalKeySizes;
|
|
}
|
|
}
|
|
|
|
public override CipherMode Mode
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.Mode;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.Mode = value;
|
|
}
|
|
}
|
|
|
|
public override PaddingMode Padding
|
|
{
|
|
get
|
|
{
|
|
return this.m_Managed.Padding;
|
|
}
|
|
set
|
|
{
|
|
this.m_Managed.Padding = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|