Browse Source

Add cache flag

akkariiin/dev
AkaneAkaza 7 years ago
parent
commit
f61bbefa95
  1. 15
      shadowsocks/encrypt.py
  2. 7
      shadowsocks/obfsplugin/auth_chain.py
  3. 2
      shadowsocks/tcprelay.py

15
shadowsocks/encrypt.py

@ -46,7 +46,7 @@ def try_cipher(key, method=None):
Encryptor(key, method) Encryptor(key, method)
def EVP_BytesToKey(password, key_len, iv_len): def EVP_BytesToKey(password, key_len, iv_len, cache):
# equivalent to OpenSSL's EVP_BytesToKey() with count 1 # equivalent to OpenSSL's EVP_BytesToKey() with count 1
# so that we make the same key and iv as nodejs version # so that we make the same key and iv as nodejs version
cached_key = '%s-%d-%d' % (password, key_len, iv_len) cached_key = '%s-%d-%d' % (password, key_len, iv_len)
@ -66,13 +66,14 @@ def EVP_BytesToKey(password, key_len, iv_len):
ms = b''.join(m) ms = b''.join(m)
key = ms[:key_len] key = ms[:key_len]
iv = ms[key_len:key_len + iv_len] iv = ms[key_len:key_len + iv_len]
if cache:
cached_keys[cached_key] = (key, iv) cached_keys[cached_key] = (key, iv)
cached_keys.sweep() cached_keys.sweep()
return key, iv return key, iv
class Encryptor(object): class Encryptor(object):
def __init__(self, key, method, iv = None): def __init__(self, key, method, iv = None, cache = False):
self.key = key self.key = key
self.method = method self.method = method
self.iv = None self.iv = None
@ -81,6 +82,7 @@ class Encryptor(object):
self.iv_buf = b'' self.iv_buf = b''
self.cipher_key = b'' self.cipher_key = b''
self.decipher = None self.decipher = None
self.cache = cache
method = method.lower() method = method.lower()
self._method_info = self.get_method_info(method) self._method_info = self.get_method_info(method)
if self._method_info: if self._method_info:
@ -105,7 +107,7 @@ class Encryptor(object):
password = common.to_bytes(password) password = common.to_bytes(password)
m = self._method_info m = self._method_info
if m[0] > 0: if m[0] > 0:
key, iv_ = EVP_BytesToKey(password, m[0], m[1]) key, iv_ = EVP_BytesToKey(password, m[0], m[1], self.cache)
else: else:
# key_length == 0 indicates we should use the key directly # key_length == 0 indicates we should use the key directly
key, iv = password, b'' key, iv = password, b''
@ -119,6 +121,9 @@ class Encryptor(object):
def encrypt(self, buf): def encrypt(self, buf):
if len(buf) == 0: if len(buf) == 0:
if not self.iv_sent:
self.iv_sent = True
return self.cipher_iv
return buf return buf
if self.iv_sent: if self.iv_sent:
return self.cipher.update(buf) return self.cipher.update(buf)
@ -155,7 +160,7 @@ def encrypt_all(password, method, op, data):
method = method.lower() method = method.lower()
(key_len, iv_len, m) = method_supported[method] (key_len, iv_len, m) = method_supported[method]
if key_len > 0: if key_len > 0:
key, _ = EVP_BytesToKey(password, key_len, iv_len) key, _ = EVP_BytesToKey(password, key_len, iv_len, True)
else: else:
key = password key = password
if op: if op:
@ -172,7 +177,7 @@ def encrypt_key(password, method):
method = method.lower() method = method.lower()
(key_len, iv_len, m) = method_supported[method] (key_len, iv_len, m) = method_supported[method]
if key_len > 0: if key_len > 0:
key, _ = EVP_BytesToKey(password, key_len, iv_len) key, _ = EVP_BytesToKey(password, key_len, iv_len, True)
else: else:
key = password key = password
return key return key

7
shadowsocks/obfsplugin/auth_chain.py

@ -349,7 +349,6 @@ class auth_chain_a(auth_base):
def pack_client_data(self, buf): def pack_client_data(self, buf):
buf = self.encryptor.encrypt(buf) buf = self.encryptor.encrypt(buf)
data = self.rnd_data(len(buf), buf, self.last_client_hash, self.random_client) data = self.rnd_data(len(buf), buf, self.last_client_hash, self.random_client)
data_len = len(data) + 8
mac_key = self.user_key + struct.pack('<I', self.pack_id) mac_key = self.user_key + struct.pack('<I', self.pack_id)
length = len(buf) ^ struct.unpack('<H', self.last_client_hash[14:])[0] length = len(buf) ^ struct.unpack('<H', self.last_client_hash[14:])[0]
data = struct.pack('<H', length) + data data = struct.pack('<H', length) + data
@ -361,7 +360,6 @@ class auth_chain_a(auth_base):
def pack_server_data(self, buf): def pack_server_data(self, buf):
buf = self.encryptor.encrypt(buf) buf = self.encryptor.encrypt(buf)
data = self.rnd_data(len(buf), buf, self.last_server_hash, self.random_server) data = self.rnd_data(len(buf), buf, self.last_server_hash, self.random_server)
data_len = len(data) + 8
mac_key = self.user_key + struct.pack('<I', self.pack_id) mac_key = self.user_key + struct.pack('<I', self.pack_id)
length = len(buf) ^ struct.unpack('<H', self.last_server_hash[14:])[0] length = len(buf) ^ struct.unpack('<H', self.last_server_hash[14:])[0]
data = struct.pack('<H', length) + data data = struct.pack('<H', length) + data
@ -372,7 +370,6 @@ class auth_chain_a(auth_base):
def pack_auth_data(self, auth_data, buf): def pack_auth_data(self, auth_data, buf):
data = auth_data data = auth_data
data_len = 12 + 4 + 16 + 4
data = data + (struct.pack('<H', self.server_info.overhead) + struct.pack('<H', 0)) data = data + (struct.pack('<H', self.server_info.overhead) + struct.pack('<H', 0))
mac_key = self.server_info.iv + self.server_info.key mac_key = self.server_info.iv + self.server_info.key
@ -565,7 +562,7 @@ class auth_chain_a(auth_base):
if length >= 4096: if length >= 4096:
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
if self.recv_id == 0: if self.recv_id == 1:
logging.info(self.no_compatible_method + ': over size') logging.info(self.no_compatible_method + ': over size')
return (b'E' * 2048, False) return (b'E' * 2048, False)
else: else:
@ -581,7 +578,7 @@ class auth_chain_a(auth_base):
)) ))
self.raw_trans = True self.raw_trans = True
self.recv_buf = b'' self.recv_buf = b''
if self.recv_id == 0: if self.recv_id == 1:
return (b'E' * 2048, False) return (b'E' * 2048, False)
else: else:
raise Exception('server_post_decrype data uncorrect checksum') raise Exception('server_post_decrype data uncorrect checksum')

2
shadowsocks/tcprelay.py

@ -266,7 +266,7 @@ class TCPRelayHandler(object):
def _create_encryptor(self, config): def _create_encryptor(self, config):
try: try:
self._encryptor = encrypt.Encryptor(config['password'], self._encryptor = encrypt.Encryptor(config['password'],
config['method']) config['method'], None, True)
return True return True
except Exception: except Exception:
self._stage = STAGE_DESTROYED self._stage = STAGE_DESTROYED

Loading…
Cancel
Save