From 0e5e86e363258f1644af09a1c055a08ec1d54cbd Mon Sep 17 00:00:00 2001 From: Regalis Date: Sun, 18 Oct 2015 22:44:30 +0300 Subject: [PATCH] v0.2.2: updated Lidgren, railgun shells can be bought, autorestart server, netstats, tutorial moloch spawning in a wall fix, misc error checks --- Launcher2/Launcher2.csproj | 2 +- Launcher2/LauncherMain.cs | 2 +- Lidgren.Network/Encryption/INetEncryption.cs | 21 - .../Encryption/NetAESEncryption.cs | 164 +------- .../Encryption/NetBlockEncryptionBase.cs | 9 +- .../Encryption/NetCryptoProviderBase.cs | 77 ++++ .../Encryption/NetCryptoProviderEncryption.cs | 59 +++ .../Encryption/NetDESEncryption.cs | 158 +------ Lidgren.Network/Encryption/NetEncryption.cs | 45 ++ .../Encryption/NetRC2Encryption.cs | 159 +------- .../Encryption/NetTripleDESEncryption.cs | 158 +------ .../Encryption/NetXorEncryption.cs | 18 +- .../Encryption/NetXteaEncryption.cs | 18 +- Lidgren.Network/Lidgren.Network.csproj | 46 ++- Lidgren.Network/Lidgren.snk | Bin 596 -> 0 bytes Lidgren.Network/NetBigInteger.cs | 15 + Lidgren.Network/NetBitWriter.cs | 3 +- Lidgren.Network/NetBuffer.Peek.cs | 2 +- Lidgren.Network/NetBuffer.Read.Reflection.cs | 14 +- Lidgren.Network/NetBuffer.Read.cs | 42 +- Lidgren.Network/NetBuffer.Write.Reflection.cs | 15 +- Lidgren.Network/NetBuffer.Write.cs | 59 ++- Lidgren.Network/NetClient.cs | 7 +- Lidgren.Network/NetConnection.Handshake.cs | 138 ++++--- Lidgren.Network/NetConnection.Latency.cs | 28 +- Lidgren.Network/NetConnection.MTU.cs | 9 +- Lidgren.Network/NetConnection.cs | 154 +++++-- Lidgren.Network/NetConnectionStatistics.cs | 105 ++--- Lidgren.Network/NetException.cs | 9 - Lidgren.Network/NetIncomingMessage.cs | 12 +- Lidgren.Network/NetNatIntroduction.cs | 63 +-- Lidgren.Network/NetOutgoingMessage.cs | 11 +- Lidgren.Network/NetPeer.Discovery.cs | 27 +- Lidgren.Network/NetPeer.Fragmentation.cs | 20 +- Lidgren.Network/NetPeer.Internal.cs | 301 ++++++++------ Lidgren.Network/NetPeer.LatencySimulation.cs | 45 +- Lidgren.Network/NetPeer.Logging.cs | 8 - Lidgren.Network/NetPeer.MessagePools.cs | 102 ++--- Lidgren.Network/NetPeer.Send.cs | 90 ++-- Lidgren.Network/NetPeer.cs | 101 +++-- Lidgren.Network/NetPeerConfiguration.cs | 92 ++++- Lidgren.Network/NetPeerStatistics.cs | 43 +- Lidgren.Network/NetQueue.cs | 36 +- Lidgren.Network/NetRandom.Implementations.cs | 281 +++++++++++++ Lidgren.Network/NetRandom.cs | 386 +++++------------- Lidgren.Network/NetRandomSeed.cs | 45 ++ Lidgren.Network/NetReliableOrderedReceiver.cs | 4 +- Lidgren.Network/NetReliableSenderChannel.cs | 69 +++- .../NetReliableSequencedReceiver.cs | 2 + .../NetReliableUnorderedReceiver.cs | 10 + Lidgren.Network/NetSRP.cs | 45 +- Lidgren.Network/NetSenderChannelBase.cs | 15 +- Lidgren.Network/NetStoredReliableMessage.cs | 4 +- Lidgren.Network/NetTime.cs | 21 +- Lidgren.Network/NetUPnP.cs | 50 ++- Lidgren.Network/NetUnreliableSenderChannel.cs | 31 +- .../NetUnreliableSequencedReceiver.cs | 8 +- .../NetUnreliableUnorderedReceiver.cs | 7 +- Lidgren.Network/NetUtility.cs | 241 +++-------- Lidgren.Network/Platform/PlatformAndroid.cs | 88 ++++ .../Platform/PlatformConstrained.cs | 86 ++++ Lidgren.Network/Platform/PlatformWin32.cs | 156 +++++++ Lidgren.Network/Platform/PlatformWinRT.cs | 102 +++++ Lidgren.Network/SenderChannelBase.cs | 11 - Subsurface/Barotrauma.csproj | 1 + Subsurface/Content/Items/Weapons/railgun.xml | 3 +- Subsurface/Source/Characters/Ragdoll.cs | 2 +- Subsurface/Source/GUI/GUITextBlock.cs | 10 +- .../GameSession/GameModes/TraitorMode.cs | 32 +- .../GameSession/GameModes/TutorialMode.cs | 3 +- .../Items/Components/Holdable/Holdable.cs | 12 + .../Source/Items/Components/ItemLabel.cs | 1 + .../Source/Items/Components/Projectile.cs | 32 +- Subsurface/Source/Items/Inventory.cs | 8 + Subsurface/Source/Items/Item.cs | 25 +- Subsurface/Source/Map/WayPoint.cs | 10 +- Subsurface/Source/Networking/GameClient.cs | 2 +- Subsurface/Source/Networking/GameServer.cs | 72 +++- Subsurface/Source/Networking/NetStats.cs | 163 ++++++++ Subsurface/Source/Networking/NetworkEvent.cs | 11 +- Subsurface/Source/Program.cs | 8 +- Subsurface/Source/Screens/NetLobbyScreen.cs | 64 ++- Subsurface/Source/Screens/ServerListScreen.cs | 5 +- Subsurface/changelog.txt | 16 + Subsurface_Solution.v12.suo | Bin 803328 -> 838144 bytes 85 files changed, 2763 insertions(+), 1866 deletions(-) delete mode 100644 Lidgren.Network/Encryption/INetEncryption.cs create mode 100644 Lidgren.Network/Encryption/NetCryptoProviderBase.cs create mode 100644 Lidgren.Network/Encryption/NetCryptoProviderEncryption.cs create mode 100644 Lidgren.Network/Encryption/NetEncryption.cs delete mode 100644 Lidgren.Network/Lidgren.snk create mode 100644 Lidgren.Network/NetRandom.Implementations.cs create mode 100644 Lidgren.Network/NetRandomSeed.cs create mode 100644 Lidgren.Network/Platform/PlatformAndroid.cs create mode 100644 Lidgren.Network/Platform/PlatformConstrained.cs create mode 100644 Lidgren.Network/Platform/PlatformWin32.cs create mode 100644 Lidgren.Network/Platform/PlatformWinRT.cs delete mode 100644 Lidgren.Network/SenderChannelBase.cs create mode 100644 Subsurface/Source/Networking/NetStats.cs 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 - - -