diff --git a/shadowsocks-csharp/Encrypt/EncryptorFactory.cs b/shadowsocks-csharp/Encrypt/EncryptorFactory.cs index e62aed06..9599adbb 100644 --- a/shadowsocks-csharp/Encrypt/EncryptorFactory.cs +++ b/shadowsocks-csharp/Encrypt/EncryptorFactory.cs @@ -1,16 +1,43 @@  +using System; +using System.Collections.Generic; +using System.Reflection; namespace Shadowsocks.Encrypt { public static class EncryptorFactory { - public static IEncryptor GetEncryptor(string method, string password) + private static Dictionary _registeredEncryptors; + + private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string) }; + + static EncryptorFactory() { - if (string.IsNullOrEmpty(method) || method.ToLowerInvariant() == "table") + _registeredEncryptors = new Dictionary(); + foreach (string method in TableEncryptor.SupportedCiphers()) + { + _registeredEncryptors.Add(method, typeof(TableEncryptor)); + } + foreach (string method in PolarSSLEncryptor.SupportedCiphers()) + { + _registeredEncryptors.Add(method, typeof(PolarSSLEncryptor)); + } + foreach (string method in SodiumEncryptor.SupportedCiphers()) { - return new TableEncryptor(method, password); + _registeredEncryptors.Add(method, typeof(SodiumEncryptor)); } + } - return new SodiumEncryptor(method, password); + public static IEncryptor GetEncryptor(string method, string password) + { + if (string.IsNullOrEmpty(method)) + { + method = "table"; + } + method = method.ToLowerInvariant(); + Type t = _registeredEncryptors[method]; + ConstructorInfo c = t.GetConstructor(_constructorTypes); + IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password }); + return result; } } } diff --git a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs index c9548acb..0e1e668f 100755 --- a/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/PolarSSLEncryptor.cs @@ -22,15 +22,22 @@ namespace Shadowsocks.Encrypt InitKey(method, password); } - protected override Dictionary getCiphers() - { - return new Dictionary { + private static Dictionary _ciphers = new Dictionary { {"aes-128-cfb", new int[]{16, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, {"aes-192-cfb", new int[]{24, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, {"aes-256-cfb", new int[]{32, 16, CIPHER_AES, PolarSSL.AES_CTX_SIZE}}, {"rc4", new int[]{16, 0, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, {"rc4-md5", new int[]{16, 16, CIPHER_RC4, PolarSSL.ARC4_CTX_SIZE}}, - }; + }; + + public static List SupportedCiphers() + { + return new List(_ciphers.Keys); + } + + protected override Dictionary getCiphers() + { + return _ciphers; } protected override void initCipher(byte[] iv, bool isCipher) diff --git a/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs b/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs index 277fb80f..8b7ac5b2 100755 --- a/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/SodiumEncryptor.cs @@ -27,12 +27,19 @@ namespace Shadowsocks.Encrypt _decryptBuf = new byte[MAX_INPUT_SIZE + SODIUM_BLOCK_SIZE]; } - protected override Dictionary getCiphers() - { - return new Dictionary { + private static Dictionary _ciphers = new Dictionary { {"salsa20", new int[]{32, 8, CIPHER_SALSA20, PolarSSL.AES_CTX_SIZE}}, {"chacha20", new int[]{32, 8, CIPHER_CHACHA20, PolarSSL.AES_CTX_SIZE}}, - }; ; + }; + + protected override Dictionary getCiphers() + { + return _ciphers; + } + + public static List SupportedCiphers() + { + return new List(_ciphers.Keys); } protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf) diff --git a/shadowsocks-csharp/Encrypt/TableEncryptor.cs b/shadowsocks-csharp/Encrypt/TableEncryptor.cs index a600a3a0..1382d7ca 100644 --- a/shadowsocks-csharp/Encrypt/TableEncryptor.cs +++ b/shadowsocks-csharp/Encrypt/TableEncryptor.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Shadowsocks.Encrypt { @@ -25,6 +26,11 @@ namespace Shadowsocks.Encrypt } } + public static List SupportedCiphers() + { + return new List(new string[]{"table"}); + } + public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { byte[] result = new byte[length];