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; } } } }