diff --git a/Launcher2/Launcher2.csproj b/Launcher2/Launcher2.csproj index 6624dcfad..89c7e279d 100644 --- a/Launcher2/Launcher2.csproj +++ b/Launcher2/Launcher2.csproj @@ -29,7 +29,7 @@ x86 pdbonly true - bin\Windows\Release\ + ..\Subsurface\bin\Windows\Release\ TRACE;WINDOWS prompt 4 diff --git a/Launcher2/LauncherMain.cs b/Launcher2/LauncherMain.cs index cc822c818..831af369a 100644 --- a/Launcher2/LauncherMain.cs +++ b/Launcher2/LauncherMain.cs @@ -542,7 +542,7 @@ namespace Launcher2 { if (e.Error!=null) { - string errorMsg = "Error while downloading: " + e.Error.InnerException.Message; + string errorMsg = "Error while downloading: " + e.Error; GUITextBlock textBlock = new GUITextBlock( new Rectangle(0, 0, 0, 0), diff --git a/Lidgren.Network/Encryption/INetEncryption.cs b/Lidgren.Network/Encryption/INetEncryption.cs deleted file mode 100644 index f82ebcf43..000000000 --- a/Lidgren.Network/Encryption/INetEncryption.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Lidgren.Network -{ - /// - /// Interface for an encryption algorithm - /// - public interface INetEncryption - { - /// - /// Encrypt an outgoing message in place - /// - bool Encrypt(NetOutgoingMessage msg); - - /// - /// Decrypt an incoming message in place - /// - bool Decrypt(NetIncomingMessage msg); - } -} diff --git a/Lidgren.Network/Encryption/NetAESEncryption.cs b/Lidgren.Network/Encryption/NetAESEncryption.cs index c8c4854a5..0fec6d5ce 100644 --- a/Lidgren.Network/Encryption/NetAESEncryption.cs +++ b/Lidgren.Network/Encryption/NetAESEncryption.cs @@ -1,172 +1,26 @@ using System; -using System.Collections.Generic; using System.IO; using System.Security.Cryptography; -using System.Text; namespace Lidgren.Network { - /// - /// AES encryption - /// - public class NetAESEncryption : INetEncryption + public class NetAESEncryption : NetCryptoProviderBase { - private readonly byte[] m_key; - private readonly byte[] m_iv; - private readonly int m_bitSize; - private static readonly List m_keysizes; - private static readonly List m_blocksizes; - - static NetAESEncryption() - { -#if !IOS && !__ANDROID__ - AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); - List temp = new List(); - foreach (KeySizes keysize in aes.LegalKeySizes) - { - for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize) - { - if (!temp.Contains(i)) - temp.Add(i); - if (i == keysize.MaxSize) - break; - } - } - m_keysizes = temp; - temp = new List(); - foreach (KeySizes keysize in aes.LegalBlockSizes) - { - for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize) - { - - if (!temp.Contains(i)) - temp.Add(i); - if (i == keysize.MaxSize) - break; - } - } - m_blocksizes = temp; -#endif - } - - /// - /// NetAESEncryption constructor - /// - public NetAESEncryption(byte[] key, byte[] iv) - { - if (!m_keysizes.Contains(key.Length * 8)) - throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes))); - - if (!m_blocksizes.Contains(iv.Length * 8)) - throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes))); - - m_key = key; - m_iv = iv; - m_bitSize = m_key.Length * 8; - } - - /// - /// NetAESEncryption constructor - /// - public NetAESEncryption(string key, int bitsize) - { - if (!m_keysizes.Contains(bitsize)) - throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes))); - - byte[] entropy = Encoding.UTF32.GetBytes(key); - // I know hardcoding salts is bad, but in this case I think it is acceptable. - HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL==")); - hmacsha512.Initialize(); - for (int i = 0; i < 1000; i++) - { - entropy = hmacsha512.ComputeHash(entropy); - } - int keylen = bitsize / 8; - m_key = new byte[keylen]; - Buffer.BlockCopy(entropy, 0, m_key, 0, keylen); - m_iv = new byte[m_blocksizes[0] / 8]; - - Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length); - m_bitSize = bitsize; - } - - /// - /// NetAESEncryption constructor - /// - public NetAESEncryption(string key) - : this(key, m_keysizes[0]) + public NetAESEncryption(NetPeer peer) + : base(peer, new AesCryptoServiceProvider()) { } - /// - /// Encrypt outgoing message - /// - public bool Encrypt(NetOutgoingMessage msg) + public NetAESEncryption(NetPeer peer, string key) + : base(peer, new AesCryptoServiceProvider()) { -#if !IOS && !__ANDROID__ - try - { - // nested usings are fun! - using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC }) - { - using (ICryptoTransform cryptoTransform = aesCryptoServiceProvider.CreateEncryptor(m_key, m_iv)) - { - using (MemoryStream memoryStream = new MemoryStream()) - { - using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write)) - { - cryptoStream.Write(msg.m_data, 0, msg.m_data.Length); - } - msg.m_data = memoryStream.ToArray(); - } - } - } - - } - catch - { - return false; - } - return true; -#else - return false; -#endif + SetKey(key); } - /// - /// Decrypt incoming message - /// - public bool Decrypt(NetIncomingMessage msg) + public NetAESEncryption(NetPeer peer, byte[] data, int offset, int count) + : base(peer, new AesCryptoServiceProvider()) { -#if !IOS && !__ANDROID__ - try - { - // nested usings are fun! - using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC }) - { - using (ICryptoTransform cryptoTransform = aesCryptoServiceProvider.CreateDecryptor(m_key, m_iv)) - { - using (MemoryStream memoryStream = new MemoryStream()) - { - using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, - CryptoStreamMode.Write)) - { - cryptoStream.Write(msg.m_data, 0, msg.m_data.Length); - } - msg.m_data = memoryStream.ToArray(); - } - } - } - - } - catch - { - return false; - } - return true; -#else - return false; -#endif + SetKey(data, offset, count); } } } diff --git a/Lidgren.Network/Encryption/NetBlockEncryptionBase.cs b/Lidgren.Network/Encryption/NetBlockEncryptionBase.cs index ed68d1723..f16aeba1e 100644 --- a/Lidgren.Network/Encryption/NetBlockEncryptionBase.cs +++ b/Lidgren.Network/Encryption/NetBlockEncryptionBase.cs @@ -6,7 +6,7 @@ namespace Lidgren.Network /// /// Base for a non-threadsafe encryption class /// - public abstract class NetBlockEncryptionBase : INetEncryption + public abstract class NetBlockEncryptionBase : NetEncryption { // temporary space for one block to avoid reallocating every time private byte[] m_tmp; @@ -19,7 +19,8 @@ namespace Lidgren.Network /// /// NetBlockEncryptionBase constructor /// - public NetBlockEncryptionBase() + public NetBlockEncryptionBase(NetPeer peer) + : base(peer) { m_tmp = new byte[BlockSize]; } @@ -27,7 +28,7 @@ namespace Lidgren.Network /// /// Encrypt am outgoing message with this algorithm; no writing can be done to the message after encryption, or message will be corrupted /// - public bool Encrypt(NetOutgoingMessage msg) + public override bool Encrypt(NetOutgoingMessage msg) { int payloadBitLength = msg.LengthBits; int numBytes = msg.LengthBytes; @@ -55,7 +56,7 @@ namespace Lidgren.Network /// /// message to decrypt /// true if successful; false if failed - public bool Decrypt(NetIncomingMessage msg) + public override bool Decrypt(NetIncomingMessage msg) { int numEncryptedBytes = msg.LengthBytes - 4; // last 4 bytes is true bit length int blockSize = BlockSize; diff --git a/Lidgren.Network/Encryption/NetCryptoProviderBase.cs b/Lidgren.Network/Encryption/NetCryptoProviderBase.cs new file mode 100644 index 000000000..e3ff3f4d5 --- /dev/null +++ b/Lidgren.Network/Encryption/NetCryptoProviderBase.cs @@ -0,0 +1,77 @@ +using System; +using System.IO; +using System.Security.Cryptography; + +namespace Lidgren.Network +{ + public abstract class NetCryptoProviderBase : NetEncryption + { + protected SymmetricAlgorithm m_algorithm; + + public NetCryptoProviderBase(NetPeer peer, SymmetricAlgorithm algo) + : base(peer) + { + m_algorithm = algo; + m_algorithm.GenerateKey(); + m_algorithm.GenerateIV(); + } + + public override void SetKey(byte[] data, int offset, int count) + { + int len = m_algorithm.Key.Length; + var key = new byte[len]; + for (int i = 0; i < len; i++) + key[i] = data[offset + (i % count)]; + m_algorithm.Key = key; + + len = m_algorithm.IV.Length; + key = new byte[len]; + for (int i = 0; i < len; i++) + key[len - 1 - i] = data[offset + (i % count)]; + m_algorithm.IV = key; + } + + public override bool Encrypt(NetOutgoingMessage msg) + { + int unEncLenBits = msg.LengthBits; + + var ms = new MemoryStream(); + var cs = new CryptoStream(ms, m_algorithm.CreateEncryptor(), CryptoStreamMode.Write); + cs.Write(msg.m_data, 0, msg.LengthBytes); + cs.Close(); + + // get results + var arr = ms.ToArray(); + ms.Close(); + + msg.EnsureBufferSize((arr.Length + 4) * 8); + msg.LengthBits = 0; // reset write pointer + msg.Write((uint)unEncLenBits); + msg.Write(arr); + msg.LengthBits = (arr.Length + 4) * 8; + + return true; + } + + public override bool Decrypt(NetIncomingMessage msg) + { + int unEncLenBits = (int)msg.ReadUInt32(); + + var ms = new MemoryStream(msg.m_data, 4, msg.LengthBytes - 4); + var cs = new CryptoStream(ms, m_algorithm.CreateDecryptor(), CryptoStreamMode.Read); + + var byteLen = NetUtility.BytesToHoldBits(unEncLenBits); + var result = m_peer.GetStorage(byteLen); + cs.Read(result, 0, byteLen); + cs.Close(); + + // TODO: recycle existing msg + + msg.m_data = result; + msg.m_bitLength = unEncLenBits; + msg.m_readPosition = 0; + + return true; + } + } +} diff --git a/Lidgren.Network/Encryption/NetCryptoProviderEncryption.cs b/Lidgren.Network/Encryption/NetCryptoProviderEncryption.cs new file mode 100644 index 000000000..d1120465b --- /dev/null +++ b/Lidgren.Network/Encryption/NetCryptoProviderEncryption.cs @@ -0,0 +1,59 @@ +using System; +using System.IO; +using System.Security.Cryptography; + +namespace Lidgren.Network +{ + public abstract class NetCryptoProviderEncryption : NetEncryption + { + public NetCryptoProviderEncryption(NetPeer peer) + : base(peer) + { + } + + protected abstract CryptoStream GetEncryptStream(MemoryStream ms); + + protected abstract CryptoStream GetDecryptStream(MemoryStream ms); + + public override bool Encrypt(NetOutgoingMessage msg) + { + int unEncLenBits = msg.LengthBits; + + var ms = new MemoryStream(); + var cs = GetEncryptStream(ms); + cs.Write(msg.m_data, 0, msg.LengthBytes); + cs.Close(); + + // get results + var arr = ms.ToArray(); + ms.Close(); + + msg.EnsureBufferSize((arr.Length + 4) * 8); + msg.LengthBits = 0; // reset write pointer + msg.Write((uint)unEncLenBits); + msg.Write(arr); + msg.LengthBits = (arr.Length + 4) * 8; + + return true; + } + + public override bool Decrypt(NetIncomingMessage msg) + { + int unEncLenBits = (int)msg.ReadUInt32(); + + var ms = new MemoryStream(msg.m_data, 4, msg.LengthBytes - 4); + var cs = GetDecryptStream(ms); + + var result = m_peer.GetStorage(unEncLenBits); + cs.Read(result, 0, NetUtility.BytesToHoldBits(unEncLenBits)); + cs.Close(); + + // TODO: recycle existing msg + + msg.m_data = result; + msg.m_bitLength = unEncLenBits; + + return true; + } + } +} diff --git a/Lidgren.Network/Encryption/NetDESEncryption.cs b/Lidgren.Network/Encryption/NetDESEncryption.cs index 02fe040e0..b6ab8135d 100644 --- a/Lidgren.Network/Encryption/NetDESEncryption.cs +++ b/Lidgren.Network/Encryption/NetDESEncryption.cs @@ -1,164 +1,26 @@ using System; -using System.Collections.Generic; using System.IO; using System.Security.Cryptography; -using System.Text; namespace Lidgren.Network { - /// - /// DES encryption - /// - public class NetDESEncryption : INetEncryption + public class NetDESEncryption : NetCryptoProviderBase { - private readonly byte[] m_key; - private readonly byte[] m_iv; - private readonly int m_bitSize; - private static readonly List m_keysizes; - private static readonly List m_blocksizes; - - static NetDESEncryption() - { - - DESCryptoServiceProvider des = new DESCryptoServiceProvider(); - List temp = new List(); - foreach (KeySizes keysize in des.LegalKeySizes) - { - for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize) - { - if (!temp.Contains(i)) - temp.Add(i); - if (i == keysize.MaxSize) - break; - } - } - m_keysizes = temp; - temp = new List(); - foreach (KeySizes keysize in des.LegalBlockSizes) - { - for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize) - { - - if (!temp.Contains(i)) - temp.Add(i); - if (i == keysize.MaxSize) - break; - } - } - m_blocksizes = temp; - } - - /// - /// NetDESEncryption constructor - /// - public NetDESEncryption(byte[] key, byte[] iv) - { - if (!m_keysizes.Contains(key.Length * 8)) - throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes))); - - if (!m_blocksizes.Contains(iv.Length * 8)) - throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes))); - - m_key = key; - m_iv = iv; - m_bitSize = m_key.Length * 8; - } - - /// - /// NetDESEncryption constructor - /// - public NetDESEncryption(string key, int bitsize) - { - if (!m_keysizes.Contains(bitsize)) - throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes))); - - byte[] entropy = Encoding.UTF32.GetBytes(key); - // I know hardcoding salts is bad, but in this case I think it is acceptable. - HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL==")); - hmacsha512.Initialize(); - for (int i = 0; i < 1000; i++) - { - entropy = hmacsha512.ComputeHash(entropy); - } - int keylen = bitsize / 8; - m_key = new byte[keylen]; - Buffer.BlockCopy(entropy, 0, m_key, 0, keylen); - m_iv = new byte[m_blocksizes[0] / 8]; - - Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length); - m_bitSize = bitsize; - } - - /// - /// NetDESEncryption constructor - /// - public NetDESEncryption(string key) - : this(key, m_keysizes[0]) + public NetDESEncryption(NetPeer peer) + : base(peer, new DESCryptoServiceProvider()) { } - /// - /// Encrypt outgoing message - /// - public bool Encrypt(NetOutgoingMessage msg) + public NetDESEncryption(NetPeer peer, string key) + : base(peer, new DESCryptoServiceProvider()) { - try - { - // nested usings are fun! - using (DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC }) - { - using (ICryptoTransform cryptoTransform = desCryptoServiceProvider.CreateEncryptor(m_key, m_iv)) - { - using (MemoryStream memoryStream = new MemoryStream()) - { - using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, - CryptoStreamMode.Write)) - { - cryptoStream.Write(msg.m_data, 0, msg.m_data.Length); - } - msg.m_data = memoryStream.ToArray(); - } - } - } - - } - catch - { - return false; - } - return true; + SetKey(key); } - /// - /// Decrypt incoming message - /// - public bool Decrypt(NetIncomingMessage msg) + public NetDESEncryption(NetPeer peer, byte[] data, int offset, int count) + : base(peer, new DESCryptoServiceProvider()) { - try - { - // nested usings are fun! - using (DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC }) - { - using (ICryptoTransform cryptoTransform = desCryptoServiceProvider.CreateDecryptor(m_key, m_iv)) - { - using (MemoryStream memoryStream = new MemoryStream()) - { - using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, - CryptoStreamMode.Write)) - { - cryptoStream.Write(msg.m_data, 0, msg.m_data.Length); - } - msg.m_data = memoryStream.ToArray(); - } - } - } - - } - catch - { - return false; - } - return true; + SetKey(data, offset, count); } } -} \ No newline at end of file +} diff --git a/Lidgren.Network/Encryption/NetEncryption.cs b/Lidgren.Network/Encryption/NetEncryption.cs new file mode 100644 index 000000000..fea1e7c33 --- /dev/null +++ b/Lidgren.Network/Encryption/NetEncryption.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; + +namespace Lidgren.Network +{ + /// + /// Interface for an encryption algorithm + /// + public abstract class NetEncryption + { + /// + /// NetPeer + /// + protected NetPeer m_peer; + + /// + /// Constructor + /// + public NetEncryption(NetPeer peer) + { + if (peer == null) + throw new NetException("Peer must not be null"); + m_peer = peer; + } + + public void SetKey(string str) + { + var bytes = System.Text.Encoding.ASCII.GetBytes(str); + SetKey(bytes, 0, bytes.Length); + } + + public abstract void SetKey(byte[] data, int offset, int count); + + /// + /// Encrypt an outgoing message in place + /// + public abstract bool Encrypt(NetOutgoingMessage msg); + + /// + /// Decrypt an incoming message in place + /// + public abstract bool Decrypt(NetIncomingMessage msg); + } +} diff --git a/Lidgren.Network/Encryption/NetRC2Encryption.cs b/Lidgren.Network/Encryption/NetRC2Encryption.cs index 7151ca201..a2d0c232b 100644 --- a/Lidgren.Network/Encryption/NetRC2Encryption.cs +++ b/Lidgren.Network/Encryption/NetRC2Encryption.cs @@ -1,165 +1,26 @@ using System; -using System.Collections.Generic; using System.IO; using System.Security.Cryptography; -using System.Text; namespace Lidgren.Network { - /// - /// RC2 encryption - /// - public class NetRC2Encryption : INetEncryption + public class NetRC2Encryption : NetCryptoProviderBase { - private readonly byte[] m_key; - private readonly byte[] m_iv; - private readonly int m_bitSize; - private static readonly List m_keysizes; - private static readonly List m_blocksizes; - - static NetRC2Encryption() - { - - RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider(); - List temp = new List(); - foreach (KeySizes keysize in rc2.LegalKeySizes) - { - for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize) - { - if (!temp.Contains(i)) - temp.Add(i); - if (i == keysize.MaxSize) - break; - } - } - m_keysizes = temp; - temp = new List(); - foreach (KeySizes keysize in rc2.LegalBlockSizes) - { - for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize) - { - - if (!temp.Contains(i)) - temp.Add(i); - if (i == keysize.MaxSize) - break; - } - } - m_blocksizes = temp; - } - - /// - /// NetRC2Encryption constructor - /// - public NetRC2Encryption(byte[] key, byte[] iv) - { - if (!m_keysizes.Contains(key.Length * 8)) - throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes))); - - if (!m_blocksizes.Contains(iv.Length * 8)) - throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes))); - - m_key = key; - m_iv = iv; - m_bitSize = m_key.Length * 8; - } - - /// - /// NetRC2Encryption constructor - /// - public NetRC2Encryption(string key, int bitsize) - { - if (!m_keysizes.Contains(bitsize)) - throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes))); - - byte[] entropy = Encoding.UTF32.GetBytes(key); - // I know hardcoding salts is bad, but in this case I think it is acceptable. - HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL==")); - hmacsha512.Initialize(); - for (int i = 0; i < 1000; i++) - { - entropy = hmacsha512.ComputeHash(entropy); - } - int keylen = bitsize / 8; - m_key = new byte[keylen]; - Buffer.BlockCopy(entropy, 0, m_key, 0, keylen); - m_iv = new byte[m_blocksizes[0] / 8]; - - Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length); - m_bitSize = bitsize; - } - - /// - /// NetRC2Encryption constructor - /// - /// - public NetRC2Encryption(string key) - : this(key, m_keysizes[0]) + public NetRC2Encryption(NetPeer peer) + : base(peer, new RC2CryptoServiceProvider()) { } - /// - /// Encrypt outgoing message - /// - public bool Encrypt(NetOutgoingMessage msg) + public NetRC2Encryption(NetPeer peer, string key) + : base(peer, new RC2CryptoServiceProvider()) { - try - { - // nested usings are fun! - using (RC2CryptoServiceProvider rc2CryptoServiceProvider = new RC2CryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC }) - { - using (ICryptoTransform cryptoTransform = rc2CryptoServiceProvider.CreateEncryptor(m_key, m_iv)) - { - using (MemoryStream memoryStream = new MemoryStream()) - { - using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, - CryptoStreamMode.Write)) - { - cryptoStream.Write(msg.m_data, 0, msg.m_data.Length); - } - msg.m_data = memoryStream.ToArray(); - } - } - } - - } - catch - { - return false; - } - return true; + SetKey(key); } - /// - /// Decrypt incoming message - /// - public bool Decrypt(NetIncomingMessage msg) + public NetRC2Encryption(NetPeer peer, byte[] data, int offset, int count) + : base(peer, new RC2CryptoServiceProvider()) { - try - { - // nested usings are fun! - using (RC2CryptoServiceProvider rc2CryptoServiceProvider = new RC2CryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC }) - { - using (ICryptoTransform cryptoTransform = rc2CryptoServiceProvider.CreateDecryptor(m_key, m_iv)) - { - using (MemoryStream memoryStream = new MemoryStream()) - { - using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, - CryptoStreamMode.Write)) - { - cryptoStream.Write(msg.m_data, 0, msg.m_data.Length); - } - msg.m_data = memoryStream.ToArray(); - } - } - } - - } - catch - { - return false; - } - return true; + SetKey(data, offset, count); } } -} \ No newline at end of file +} diff --git a/Lidgren.Network/Encryption/NetTripleDESEncryption.cs b/Lidgren.Network/Encryption/NetTripleDESEncryption.cs index 5495e0721..58044d52c 100644 --- a/Lidgren.Network/Encryption/NetTripleDESEncryption.cs +++ b/Lidgren.Network/Encryption/NetTripleDESEncryption.cs @@ -1,164 +1,26 @@ using System; -using System.Collections.Generic; using System.IO; using System.Security.Cryptography; -using System.Text; namespace Lidgren.Network { - /// - /// Triple DES encryption - /// - public class NetTripleDESEncryption : INetEncryption + public class NetTripleDESEncryption : NetCryptoProviderBase { - private readonly byte[] m_key; - private readonly byte[] m_iv; - private readonly int m_bitSize; - private static readonly List m_keysizes; - private static readonly List m_blocksizes; - - static NetTripleDESEncryption() - { - - TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider(); - List temp = new List(); - foreach (KeySizes keysize in tripleDES.LegalKeySizes) - { - for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize) - { - if (!temp.Contains(i)) - temp.Add(i); - if (i == keysize.MaxSize) - break; - } - } - m_keysizes = temp; - temp = new List(); - foreach (KeySizes keysize in tripleDES.LegalBlockSizes) - { - for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize) - { - - if (!temp.Contains(i)) - temp.Add(i); - if (i == keysize.MaxSize) - break; - } - } - m_blocksizes = temp; - } - - /// - /// NetTriplsDESEncryption constructor - /// - public NetTripleDESEncryption(byte[] key, byte[] iv) - { - if (!m_keysizes.Contains(key.Length * 8)) - throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes))); - - if (!m_blocksizes.Contains(iv.Length * 8)) - throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes))); - - m_key = key; - m_iv = iv; - m_bitSize = m_key.Length * 8; - } - - /// - /// NetTriplsDESEncryption constructor - /// - public NetTripleDESEncryption(string key, int bitsize) - { - if (!m_keysizes.Contains(bitsize)) - throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes))); - - byte[] entropy = Encoding.UTF32.GetBytes(key); - // I know hardcoding salts is bad, but in this case I think it is acceptable. - HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL==")); - hmacsha512.Initialize(); - for (int i = 0; i < 1000; i++) - { - entropy = hmacsha512.ComputeHash(entropy); - } - int keylen = bitsize / 8; - m_key = new byte[keylen]; - Buffer.BlockCopy(entropy, 0, m_key, 0, keylen); - m_iv = new byte[m_blocksizes[0] / 8]; - - Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length); - m_bitSize = bitsize; - } - - /// - /// NetTriplsDESEncryption constructor - /// - public NetTripleDESEncryption(string key) - : this(key, m_keysizes[0]) + public NetTripleDESEncryption(NetPeer peer) + : base(peer, new TripleDESCryptoServiceProvider()) { } - /// - /// Encrypt outgoing message - /// - public bool Encrypt(NetOutgoingMessage msg) + public NetTripleDESEncryption(NetPeer peer, string key) + : base(peer, new TripleDESCryptoServiceProvider()) { - try - { - // nested usings are fun! - using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC }) - { - using (ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateEncryptor(m_key, m_iv)) - { - using (MemoryStream memoryStream = new MemoryStream()) - { - using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, - CryptoStreamMode.Write)) - { - cryptoStream.Write(msg.m_data, 0, msg.m_data.Length); - } - msg.m_data = memoryStream.ToArray(); - } - } - } - - } - catch - { - return false; - } - return true; + SetKey(key); } - /// - /// Decrypt incoming message - /// - public bool Decrypt(NetIncomingMessage msg) + public NetTripleDESEncryption(NetPeer peer, byte[] data, int offset, int count) + : base(peer, new TripleDESCryptoServiceProvider()) { - try - { - // nested usings are fun! - using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC }) - { - using (ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateDecryptor(m_key, m_iv)) - { - using (MemoryStream memoryStream = new MemoryStream()) - { - using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, - CryptoStreamMode.Write)) - { - cryptoStream.Write(msg.m_data, 0, msg.m_data.Length); - } - msg.m_data = memoryStream.ToArray(); - } - } - } - - } - catch - { - return false; - } - return true; + SetKey(data, offset, count); } } -} \ No newline at end of file +} diff --git a/Lidgren.Network/Encryption/NetXorEncryption.cs b/Lidgren.Network/Encryption/NetXorEncryption.cs index e9c3d5868..04d8e50fd 100644 --- a/Lidgren.Network/Encryption/NetXorEncryption.cs +++ b/Lidgren.Network/Encryption/NetXorEncryption.cs @@ -7,22 +7,30 @@ namespace Lidgren.Network /// /// Example class; not very good encryption /// - public class NetXorEncryption : INetEncryption + public class NetXorEncryption : NetEncryption { private byte[] m_key; /// /// NetXorEncryption constructor /// - public NetXorEncryption(byte[] key) + public NetXorEncryption(NetPeer peer, byte[] key) + : base(peer) { m_key = key; } + public override void SetKey(byte[] data, int offset, int count) + { + m_key = new byte[count]; + Array.Copy(data, offset, m_key, 0, count); + } + /// /// NetXorEncryption constructor /// - public NetXorEncryption(string key) + public NetXorEncryption(NetPeer peer, string key) + : base(peer) { m_key = Encoding.UTF8.GetBytes(key); } @@ -30,7 +38,7 @@ namespace Lidgren.Network /// /// Encrypt an outgoing message /// - public bool Encrypt(NetOutgoingMessage msg) + public override bool Encrypt(NetOutgoingMessage msg) { int numBytes = msg.LengthBytes; for (int i = 0; i < numBytes; i++) @@ -44,7 +52,7 @@ namespace Lidgren.Network /// /// Decrypt an incoming message /// - public bool Decrypt(NetIncomingMessage msg) + public override bool Decrypt(NetIncomingMessage msg) { int numBytes = msg.LengthBytes; for (int i = 0; i < numBytes; i++) diff --git a/Lidgren.Network/Encryption/NetXteaEncryption.cs b/Lidgren.Network/Encryption/NetXteaEncryption.cs index 258c7cf02..600e408e6 100644 --- a/Lidgren.Network/Encryption/NetXteaEncryption.cs +++ b/Lidgren.Network/Encryption/NetXteaEncryption.cs @@ -44,7 +44,8 @@ namespace Lidgren.Network /// /// 16 byte key /// - public NetXtea(byte[] key, int rounds) + public NetXtea(NetPeer peer, byte[] key, int rounds) + : base(peer) { if (key.Length < c_keySize) throw new NetException("Key too short!"); @@ -73,19 +74,26 @@ namespace Lidgren.Network /// /// 16 byte key /// - public NetXtea(byte[] key) - : this(key, 32) + public NetXtea(NetPeer peer, byte[] key) + : this(peer, key, 32) { } /// /// String to hash for key /// - public NetXtea(string key) - : this(SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(key)), 32) + public NetXtea(NetPeer peer, string key) + : this(peer, NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(key)), 32) { } + public override void SetKey(byte[] data, int offset, int length) + { + var key = NetUtility.ComputeSHAHash(data, offset, length); + NetException.Assert(key.Length >= 16); + SetKey(key, 0, 16); + } + /// /// Encrypts a block of bytes /// diff --git a/Lidgren.Network/Lidgren.Network.csproj b/Lidgren.Network/Lidgren.Network.csproj index a854cb1ef..b5ea57927 100644 --- a/Lidgren.Network/Lidgren.Network.csproj +++ b/Lidgren.Network/Lidgren.Network.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -10,7 +10,7 @@ Properties Lidgren.Network Lidgren.Network - v3.5 + v4.0 512 publish\ true @@ -39,6 +39,7 @@ 4 AllRules.ruleset bin\Debug\Lidgren.Network.XML + false pdbonly @@ -48,27 +49,34 @@ prompt 4 AllRules.ruleset - - - true - - - Lidgren.snk + false + - - + + Code + + + + Code + + - - - - + + Code + + + Code + + + Code + @@ -109,6 +117,8 @@ + + @@ -126,8 +136,11 @@ + + + + - @@ -151,9 +164,6 @@ true - - -