Browse Source

refact

tags/3.0
Gang Zhuo 9 years ago
parent
commit
098640e792
10 changed files with 85 additions and 64 deletions
  1. +2
    -2
      shadowsocks-csharp/Controller/Service/TCPRelay.cs
  2. +3
    -3
      shadowsocks-csharp/Controller/Service/UDPRelay.cs
  3. +4
    -2
      shadowsocks-csharp/Encryption/EncryptorBase.cs
  4. +3
    -3
      shadowsocks-csharp/Encryption/EncryptorFactory.cs
  5. +1
    -1
      shadowsocks-csharp/Encryption/IEncryptor.cs
  6. +56
    -37
      shadowsocks-csharp/Encryption/IVEncryptor.cs
  7. +2
    -2
      shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs
  8. +2
    -2
      shadowsocks-csharp/Encryption/SodiumEncryptor.cs
  9. +3
    -3
      shadowsocks-csharp/Encryption/TableEncryptor.cs
  10. +9
    -9
      test/UnitTest.cs

+ 2
- 2
shadowsocks-csharp/Controller/Service/TCPRelay.cs View File

@@ -125,7 +125,7 @@ namespace Shadowsocks.Controller
{ {
throw new ArgumentException("No server configured"); throw new ArgumentException("No server configured");
} }
this.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.one_time_auth);
this.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.one_time_auth, false);
this.server = server; this.server = server;
} }
@@ -586,7 +586,7 @@ namespace Shadowsocks.Controller
{ {
return; return;
} }
encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend, false);
encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend);
} }
remote.BeginSend(connetionSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeRemoteSendCallback), null); remote.BeginSend(connetionSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeRemoteSendCallback), null);


+ 3
- 3
shadowsocks-csharp/Controller/Service/UDPRelay.cs View File

@@ -74,12 +74,12 @@ namespace Shadowsocks.Controller
} }
public void Send(byte[] data, int length) public void Send(byte[] data, int length)
{ {
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth);
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth, true);
byte[] dataIn = new byte[length - 3 + IVEncryptor.ONETIMEAUTH_BYTES]; byte[] dataIn = new byte[length - 3 + IVEncryptor.ONETIMEAUTH_BYTES];
Array.Copy(data, 3, dataIn, 0, length - 3); Array.Copy(data, 3, dataIn, 0, length - 3);
byte[] dataOut = new byte[length - 3 + 16 + IVEncryptor.ONETIMEAUTH_BYTES]; byte[] dataOut = new byte[length - 3 + 16 + IVEncryptor.ONETIMEAUTH_BYTES];
int outlen; int outlen;
encryptor.Encrypt(dataIn, length - 3, dataOut, out outlen, true);
encryptor.Encrypt(dataIn, length - 3, dataOut, out outlen);
_remote.SendTo(dataOut, outlen, SocketFlags.None, _remoteEndPoint); _remote.SendTo(dataOut, outlen, SocketFlags.None, _remoteEndPoint);
} }
public void Receive() public void Receive()
@@ -97,7 +97,7 @@ namespace Shadowsocks.Controller
byte[] dataOut = new byte[bytesRead]; byte[] dataOut = new byte[bytesRead];
int outlen; int outlen;
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth);
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.one_time_auth, true);
encryptor.Decrypt(_buffer, bytesRead, dataOut, out outlen); encryptor.Decrypt(_buffer, bytesRead, dataOut, out outlen);
byte[] sendBuf = new byte[outlen + 3]; byte[] sendBuf = new byte[outlen + 3];


+ 4
- 2
shadowsocks-csharp/Encryption/EncryptorBase.cs View File

@@ -8,16 +8,18 @@ namespace Shadowsocks.Encryption
{ {
public const int MAX_INPUT_SIZE = 32768; public const int MAX_INPUT_SIZE = 32768;
protected EncryptorBase(string method, string password, bool onetimeauth)
protected EncryptorBase(string method, string password, bool onetimeauth, bool isudp)
{ {
Method = method; Method = method;
Password = password; Password = password;
OnetimeAuth = onetimeauth; OnetimeAuth = onetimeauth;
IsUDP = isudp;
} }
protected string Method; protected string Method;
protected string Password; protected string Password;
protected bool OnetimeAuth; protected bool OnetimeAuth;
protected bool IsUDP;
protected byte[] GetPasswordHash() protected byte[] GetPasswordHash()
{ {
@@ -26,7 +28,7 @@ namespace Shadowsocks.Encryption
return hash; return hash;
} }
public abstract void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp);
public abstract void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
public abstract void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength); public abstract void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength);


+ 3
- 3
shadowsocks-csharp/Encryption/EncryptorFactory.cs View File

@@ -8,7 +8,7 @@ namespace Shadowsocks.Encryption
{ {
private static Dictionary<string, Type> _registeredEncryptors; private static Dictionary<string, Type> _registeredEncryptors;
private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string), typeof(bool) };
private static Type[] _constructorTypes = new Type[] { typeof(string), typeof(string), typeof(bool), typeof(bool) };
static EncryptorFactory() static EncryptorFactory()
{ {
@@ -27,7 +27,7 @@ namespace Shadowsocks.Encryption
} }
} }
public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth)
public static IEncryptor GetEncryptor(string method, string password, bool onetimeauth, bool isudp)
{ {
if (string.IsNullOrEmpty(method)) if (string.IsNullOrEmpty(method))
{ {
@@ -36,7 +36,7 @@ namespace Shadowsocks.Encryption
method = method.ToLowerInvariant(); method = method.ToLowerInvariant();
Type t = _registeredEncryptors[method]; Type t = _registeredEncryptors[method];
ConstructorInfo c = t.GetConstructor(_constructorTypes); ConstructorInfo c = t.GetConstructor(_constructorTypes);
IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password, onetimeauth });
IEncryptor result = (IEncryptor)c.Invoke(new object[] { method, password, onetimeauth, isudp });
return result; return result;
} }
} }


+ 1
- 1
shadowsocks-csharp/Encryption/IEncryptor.cs View File

@@ -6,7 +6,7 @@ namespace Shadowsocks.Encryption
{ {
public interface IEncryptor : IDisposable public interface IEncryptor : IDisposable
{ {
void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp);
void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength); void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength);
} }
} }

+ 56
- 37
shadowsocks-csharp/Encryption/IVEncryptor.cs View File

@@ -40,8 +40,8 @@ namespace Shadowsocks.Encryption
protected uint counter = 0; protected uint counter = 0;
protected byte[] _keyBuffer = null; protected byte[] _keyBuffer = null;
public IVEncryptor(string method, string password, bool onetimeauth)
: base(method, password, onetimeauth)
public IVEncryptor(string method, string password, bool onetimeauth, bool isudp)
: base(method, password, onetimeauth, isudp)
{ {
InitKey(method, password); InitKey(method, password);
} }
@@ -183,38 +183,65 @@ namespace Shadowsocks.Encryption
return hash; return hash;
} }
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp)
protected void reactBuffer4TCP(byte[] buf, ref int length)
{
if (!_encryptIVSent)
{
int headLen = getHeadLen(buf, length);
int dataLen = length - headLen;
buf[0] |= ONETIMEAUTH_FLAG;
byte[] hash = genOnetimeAuthHash(buf, headLen);
Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen);
Buffer.BlockCopy(hash, 0, buf, headLen, ONETIMEAUTH_BYTES);
hash = genHash(buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen);
Buffer.BlockCopy(hash, 0, buf, headLen + ONETIMEAUTH_BYTES + CLEN_BYTES, ONETIMEAUTH_BYTES);
byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)dataLen));
Buffer.BlockCopy(lenBytes, 0, buf, headLen + ONETIMEAUTH_BYTES, CLEN_BYTES);
length = headLen + ONETIMEAUTH_BYTES + AUTH_BYTES + dataLen;
}
else
{
byte[] hash = genHash(buf, 0, length);
Buffer.BlockCopy(buf, 0, buf, AUTH_BYTES, length);
byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)length));
Buffer.BlockCopy(lenBytes, 0, buf, 0, CLEN_BYTES);
Buffer.BlockCopy(hash, 0, buf, CLEN_BYTES, ONETIMEAUTH_BYTES);
length += AUTH_BYTES;
}
}
protected void reactBuffer4UDP(byte[] buf, ref int length)
{
buf[0] |= ONETIMEAUTH_FLAG;
byte[] hash = genOnetimeAuthHash(buf, length);
Buffer.BlockCopy(hash, 0, buf, length, ONETIMEAUTH_BYTES);
length += ONETIMEAUTH_BYTES;
}
protected void reactBuffer(byte[] buf, ref int length)
{
if (OnetimeAuth && ivLen > 0)
{
if (!IsUDP)
{
reactBuffer4TCP(buf, ref length);
}
else
{
reactBuffer4UDP(buf, ref length);
}
}
}
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
{ {
if (!_encryptIVSent) if (!_encryptIVSent)
{ {
_encryptIVSent = true;
randBytes(outbuf, ivLen); randBytes(outbuf, ivLen);
initCipher(outbuf, true); initCipher(outbuf, true);
outlength = length + ivLen; outlength = length + ivLen;
if (OnetimeAuth && ivLen > 0)
{
if(!udp)
{
int headLen = getHeadLen(buf, length);
int dataLen = length - headLen;
buf[0] |= ONETIMEAUTH_FLAG;
byte[] hash = genOnetimeAuthHash(buf, headLen);
Buffer.BlockCopy(buf, headLen, buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen);
Buffer.BlockCopy(hash, 0, buf, headLen, ONETIMEAUTH_BYTES);
hash = genHash(buf, headLen + ONETIMEAUTH_BYTES + AUTH_BYTES, dataLen);
Buffer.BlockCopy(hash, 0, buf, headLen + ONETIMEAUTH_BYTES + CLEN_BYTES, ONETIMEAUTH_BYTES);
byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)dataLen));
Buffer.BlockCopy(lenBytes, 0, buf, headLen + ONETIMEAUTH_BYTES, CLEN_BYTES);
length = headLen + ONETIMEAUTH_BYTES + AUTH_BYTES + dataLen;
}
else
{
buf[0] |= ONETIMEAUTH_FLAG;
byte[] hash = genOnetimeAuthHash(buf, length);
Buffer.BlockCopy(hash, 0, buf, length, ONETIMEAUTH_BYTES);
length += ONETIMEAUTH_BYTES;
}
}
reactBuffer(buf, ref length);
_encryptIVSent = true;
lock (tempbuf) lock (tempbuf)
{ {
cipherUpdate(true, length, buf, tempbuf); cipherUpdate(true, length, buf, tempbuf);
@@ -224,15 +251,7 @@ namespace Shadowsocks.Encryption
} }
else else
{ {
if (OnetimeAuth && ivLen > 0)
{
byte[] hash = genHash(buf, 0, length);
Buffer.BlockCopy(buf, 0, buf, AUTH_BYTES, length);
byte[] lenBytes = BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)length));
Buffer.BlockCopy(lenBytes, 0, buf, 0, CLEN_BYTES);
Buffer.BlockCopy(hash, 0, buf, CLEN_BYTES, ONETIMEAUTH_BYTES);
length += AUTH_BYTES;
}
reactBuffer(buf, ref length);
outlength = length; outlength = length;
cipherUpdate(true, length, buf, outbuf); cipherUpdate(true, length, buf, outbuf);
} }


+ 2
- 2
shadowsocks-csharp/Encryption/PolarSSLEncryptor.cs View File

@@ -16,8 +16,8 @@ namespace Shadowsocks.Encryption
private IntPtr _encryptCtx = IntPtr.Zero; private IntPtr _encryptCtx = IntPtr.Zero;
private IntPtr _decryptCtx = IntPtr.Zero; private IntPtr _decryptCtx = IntPtr.Zero;
public PolarSSLEncryptor(string method, string password, bool onetimeauth)
: base(method, password, onetimeauth)
public PolarSSLEncryptor(string method, string password, bool onetimeauth, bool isudp)
: base(method, password, onetimeauth, isudp)
{ {
InitKey(method, password); InitKey(method, password);
} }


+ 2
- 2
shadowsocks-csharp/Encryption/SodiumEncryptor.cs View File

@@ -20,8 +20,8 @@ namespace Shadowsocks.Encryption
protected ulong _encryptIC; protected ulong _encryptIC;
protected ulong _decryptIC; protected ulong _decryptIC;
public SodiumEncryptor(string method, string password, bool onetimeauth)
: base(method, password, onetimeauth)
public SodiumEncryptor(string method, string password, bool onetimeauth, bool isudp)
: base(method, password, onetimeauth, isudp)
{ {
InitKey(method, password); InitKey(method, password);
} }


+ 3
- 3
shadowsocks-csharp/Encryption/TableEncryptor.cs View File

@@ -6,8 +6,8 @@ namespace Shadowsocks.Encryption
public class TableEncryptor public class TableEncryptor
: EncryptorBase : EncryptorBase
{ {
public TableEncryptor(string method, string password, bool onetimeauth)
: base(method, password, onetimeauth)
public TableEncryptor(string method, string password, bool onetimeauth, bool isudp)
: base(method, password, onetimeauth, isudp)
{ {
byte[] hash = GetPasswordHash(); byte[] hash = GetPasswordHash();
// TODO endian // TODO endian
@@ -31,7 +31,7 @@ namespace Shadowsocks.Encryption
return new List<string>(new string[]{"table"}); return new List<string>(new string[]{"table"});
} }
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength, bool udp)
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength)
{ {
byte[] result = new byte[length]; byte[] result = new byte[length];
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)


+ 9
- 9
test/UnitTest.cs View File

@@ -31,21 +31,21 @@ namespace test
int outLen2 = 0; int outLen2 = 0;
var random = new Random(); var random = new Random();
random.NextBytes(plain); random.NextBytes(plain);
encryptor.Encrypt(plain, plain.Length, cipher, out outLen, false);
encryptor.Encrypt(plain, plain.Length, cipher, out outLen);
decryptor.Decrypt(cipher, outLen, plain2, out outLen2); decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
Assert.AreEqual(plain.Length, outLen2); Assert.AreEqual(plain.Length, outLen2);
for (int j = 0; j < plain.Length; j++) for (int j = 0; j < plain.Length; j++)
{ {
Assert.AreEqual(plain[j], plain2[j]); Assert.AreEqual(plain[j], plain2[j]);
} }
encryptor.Encrypt(plain, 1000, cipher, out outLen, false);
encryptor.Encrypt(plain, 1000, cipher, out outLen);
decryptor.Decrypt(cipher, outLen, plain2, out outLen2); decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
Assert.AreEqual(1000, outLen2); Assert.AreEqual(1000, outLen2);
for (int j = 0; j < outLen2; j++) for (int j = 0; j < outLen2; j++)
{ {
Assert.AreEqual(plain[j], plain2[j]); Assert.AreEqual(plain[j], plain2[j]);
} }
encryptor.Encrypt(plain, 12333, cipher, out outLen, false);
encryptor.Encrypt(plain, 12333, cipher, out outLen);
decryptor.Decrypt(cipher, outLen, plain2, out outLen2); decryptor.Decrypt(cipher, outLen, plain2, out outLen2);
Assert.AreEqual(12333, outLen2); Assert.AreEqual(12333, outLen2);
for (int j = 0; j < outLen2; j++) for (int j = 0; j < outLen2; j++)
@@ -84,8 +84,8 @@ namespace test
{ {
IEncryptor encryptor; IEncryptor encryptor;
IEncryptor decryptor; IEncryptor decryptor;
encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false);
decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false);
encryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false, false);
decryptor = new PolarSSLEncryptor("aes-256-cfb", "barfoo!", false, false);
RunEncryptionRound(encryptor, decryptor); RunEncryptionRound(encryptor, decryptor);
} }
} }
@@ -124,8 +124,8 @@ namespace test
var random = new Random(); var random = new Random();
IEncryptor encryptor; IEncryptor encryptor;
IEncryptor decryptor; IEncryptor decryptor;
encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false);
decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false);
encryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false, false);
decryptor = new PolarSSLEncryptor("rc4-md5", "barfoo!", false, false);
RunEncryptionRound(encryptor, decryptor); RunEncryptionRound(encryptor, decryptor);
} }
} }
@@ -164,8 +164,8 @@ namespace test
var random = new Random(); var random = new Random();
IEncryptor encryptor; IEncryptor encryptor;
IEncryptor decryptor; IEncryptor decryptor;
encryptor = new SodiumEncryptor("salsa20", "barfoo!", false);
decryptor = new SodiumEncryptor("salsa20", "barfoo!", false);
encryptor = new SodiumEncryptor("salsa20", "barfoo!", false, false);
decryptor = new SodiumEncryptor("salsa20", "barfoo!", false, false);
RunEncryptionRound(encryptor, decryptor); RunEncryptionRound(encryptor, decryptor);
} }
} }


Loading…
Cancel
Save