def decrypt(self, cipher_line): if not util.is_encrypted(cipher_line): raise KarnError('"%s" is not encrypted!' % cipher_line) # convert from base 32 to bytes literal cipherbytes = bytearray.fromhex(unicode(util.inttohex(int(cipher_line.strip(), 32)))) output = bytearray() # start at byte 1 because byte 0 is the guard byte for i in xrange(1, len(cipherbytes), BLOCK_SIZE): cipher = cipherbytes[i:i+BLOCK_SIZE] # + is the concatenation operator in python # ^ is the xor operator leftmd = bytearray(hashlib.sha1(str(util.right(cipher)) + str(self.rightkey)).digest()) leftcipher = util.left(cipher) plaintext = bytearray(leftmd[i] ^ leftcipher[i] for i in xrange(len(leftmd))) rightmd = bytearray(hashlib.sha1(str(plaintext) + str(self.leftkey)).digest()) rightcipher = util.right(cipher) plaintext.extend(bytearray(rightmd[i] ^ rightcipher[i] for i in xrange(len(rightmd)))) # break if we decrypted a null byte output.extend(plaintext.partition('\x00')[0]) if '\x00' in plaintext: break # we are expecting an ascii string, so print debug info # if any decrypted character is out of ascii range if any(i > 127 for i in output): print 'couldn\'t decrypt ciphertext: %s' % cipher_line print 'with key: %d' % self.key print 'output: %s' % output raise DecryptionError(cipher_line, self.key, output) return str(output)
if __name__ == '__main__': parse_arguments() print 'Starting 0\/3r34sY NetSecurity Client' print 'Commands will ' + ('' if Settings.encrypt else 'not ') + 'be encrypted' # connect to sqlite3 db dbconn = sqlite3.connect(Settings.identsdbfile) dbconn.text_factory = str # Connect to server and open stream with contextlib.closing(socket.create_connection((Settings.monitor, Settings.monitor_port))) as sock: for line in sock.makefile(): print 'incoming', if util.is_encrypted(line): try: line = mycipher.decrypt(line) except karn.DecryptionError as de: util.print_decryption_debug_info(de) continue print '[encrypted]', print '>>>', line.strip() response = process_monitor_directive(line) if response: print 'outgoing', outgoingtext = response.strip() if util.is_encrypted(response): print '[encrypted]', try:
def handle(self): if self.session is None: self.session = diffie_hellman.Session(Settings.privatekey) #rfile is a file-like handle to our socket for line in self.rfile: if util.is_encrypted(line): line = self.cipher.decrypt(line) chkprint('incoming [encrypted] >>> %s' % line.strip()) else: chkprint('incoming >>> %s' % line.strip()) directive, args = [i.strip() for i in line.split(':', 1)] if Settings.mode == 'manual': if directive == 'WAITING': self.send_command(raw_input('Enter server command: ') + '\n') elif directive == 'PARTICIPANT_PASSWORD_CHECKSUM': check = self.check_checksum(args.strip()) # hangup if in strict mode and checksum fails if Settings.enforcechecksums and not check: return elif directive == 'REQUIRE': if args == 'IDENT': if Settings.encrypt: self.send_command('IDENT %s %s\n' % (Settings.ident, util.base32(self.session.public_key))) else: self.send_command('IDENT %s\n' % Settings.ident) elif args == 'QUIT': command = 'QUIT\n' self.send_command(self.cipher.encrypt(command) if self.cipher else command) elif args == 'ALIVE': global cookie command = 'ALIVE %s\n' % util.getcookie(self.dbconn, Settings.ident) self.send_command(self.cipher.encrypt(command) if self.cipher else command) elif args == 'ROUNDS': command = 'ROUNDS %d' % Settings.proof_rounds self.send_command(self.cipher.encrypt(command) if self.cipher else command) elif args == 'SUBSET_A': command = 'SUBSET_A %s' % ' '.join(str(s) for s in self.verifier.subset_a) self.send_command(self.cipher.encrypt(command) if self.cipher else command) elif args == 'TRANSFER_RESPONSE': #use a whitelist instead of spending time on calculations #accept_transfer = self.transfer_request['recipient'] in Settings.ident_whitelist accept_transfer = self.verifier.is_valid() chkprint(self.verifier.is_valid()) command = 'TRANSFER_RESPONSE %s' % ('ACCEPT' if accept_transfer else 'DECLINE') self.send_command(self.cipher.encrypt(command) if self.cipher else command) elif directive == 'TRANSFER': recipient, amount, _, sender = args.split() self.transfer_request = {'recipient':recipient, 'amount':amount, 'sender':sender} elif directive == 'RESULT': args = args.split() if args[0] == 'IDENT' and Settings.encrypt: self.session.set_monitor_key(int(args[1], 32)) self.cipher = karn.Cipher(self.session.shared_secret) elif args[0] == 'SUBSET_K': self.verifier.subset_k = tuple(int(i) for i in args[1:]) elif args[0] == 'SUBSET_J': self.verifier.subset_j = tuple(int(i) for i in args[1:]) elif args[0] == 'PUBLIC_KEY': self.verifier.v, self.verifier.n = (int(i) for i in args[1:]) elif args[0] == 'AUTHORIZE_SET': self.verifier.authorize_set = tuple(int(i) for i in args[1:])