def connect_receive(self, reply=None): """ Process a connect message from server (phase > 1)""" msg = {'type': 'connect', 'phase': reply['phase']+1, 'name': self.name, 'id': self.id, 'ciphers': ['NONE'], 'data': {}} if reply['phase'] == 2: self.cipher_suite = reply['ciphers'] # keys pair creation self.public_key, self.private_key = keys.verify_cipher_suite(self.cipher_suite) msg['ciphers'] = reply['ciphers'] # client random self.rand_client = os.urandom(32) msg['data'] = {'public_key': self.public_key, 'client_random': base64.b64encode(self.rand_client)} if reply['phase'] == 4: self.server_public_key = keys.deserialize_public_key(base64.b64decode(reply['data']['public_key'])) self.master_secret = keys.generate_master_secret(self.server_public_key, self.private_key) # get random server self.rand_srv = base64.b64decode(reply['data']['server_random']) self.final_master_secret = keys.generate_final_master_secret(self.master_secret, self.rand_client + self.rand_srv) # Make the secret secure self.rand_client = None session_connected = True # print '-------------------------------------------\nServer-Client Handshake completed!!\n-------------------------------------------' if session_connected: print '-------------------------------------------\nBegin Client-Connect!!\n-------------------------------------------' # Automatic list of clients list self.list_clients() print '\n',self.need_help() return self.sock.send(msg)
def send(self, obj): """Send an object to this client. """ try: if obj['type'] == 'secure': new_public_key, new_private_key = keys.verify_cipher_suite( self.cipher_suite) #print type(self.received_public_key) new_master_secret = keys.generate_master_secret( self.received_public_key, new_private_key) self.rand_server = os.urandom(32) self.final_master_secret = keys.generate_final_master_secret( new_master_secret, self.random_client + self.rand_server) ciphertext, server_iv = keys.encrypt(self.cipher_suite, self.final_master_secret, obj['payload']) obj['payload'] = { 'ciphertext': base64.b64encode(ciphertext), 'public_key': new_public_key } server_hash = keys.message_authentication( self.cipher_suite, self.final_master_secret, ciphertext) obj['sa-data'] = { 'hash': base64.b64encode(server_hash), 'iv': base64.b64encode(server_iv), 'random': base64.b64encode(self.rand_server) } self.private_key = new_private_key self.bufout += json.dumps(obj) + "\n\n" else: self.bufout += json.dumps(obj) + "\n\n" except: # It should never happen! And not be reported to the client! logging.exception("Client.send(%s)", self)
def send_client_com(self,dst,cleartext): """ Process a client-com message from client """ msg = {'type':'client-com', 'src': self.id,'dst': dst, 'data': {}} # Client in session client = self.clients[str(dst)] # Cipher: new private key + old public key client.new_public_key,client.new_private_key = keys.verify_cipher_suite(client.cipher_suite) client.client_client_master_secret = keys.generate_master_secret(client.received_public_key, client.new_private_key) client.random = os.urandom(32) client.client_client_final_master = keys.generate_final_master_secret(client.client_client_master_secret,client.received_random + client.random) ciphertext ,iv = keys.encrypt(client.cipher_suite,client.client_client_final_master ,cleartext) client.digest = keys.message_authentication(client.cipher_suite, client.client_client_final_master, ciphertext) client.private_key = client.new_private_key msg['data'] = {'hash':base64.b64encode(client.digest), 'iv' : base64.b64encode(iv), 'public_key': client.new_public_key, 'ciphertext': base64.b64encode(ciphertext), 'random': base64.b64encode(client.random) } self.secure_send(msg)
def receive_client_com(self,reply): """ Process a client-com message from client """ # Client in session client = self.clients[str(reply['src'])] # Decipher: public key received + old private key ciphertext = base64.b64decode(reply['data']['ciphertext']) client.received_public_key = keys.deserialize_public_key(base64.b64decode(reply['data']['public_key'])) digest = base64.b64decode(reply['data']['hash']) client.received_random = base64.b64decode(reply['data']['random']) iv = base64.b64decode(reply['data']['iv']) client.client_client_master_secret = keys.generate_master_secret(client.received_public_key, client.private_key) client.client_client_final_master = keys.generate_final_master_secret(client.client_client_master_secret, client.random + client.received_random) client.digest = keys.message_authentication(client.cipher_suite,client.client_client_final_master, ciphertext) client.public_key = client.received_public_key if client.digest != digest: logging.warning('Client Hash and Server Hash do not match!') cleartext = keys.decrypt(client.cipher_suite, client.client_client_final_master, ciphertext, iv) print '__________________________________________\n' print 'Client:',str(reply['src']),'# ',cleartext print '__________________________________________\n' if cleartext != '': self.send_client_ack(reply['src'])
def secure_receive(self, msg_json): """ Process a secure message from server """ # Decipher: public key received + old private key ciphertext = base64.b64decode(msg_json['payload']['ciphertext']) public_key = keys.deserialize_public_key(base64.b64decode(msg_json['payload']['public_key'])) server_hash = base64.b64decode(msg_json['sa-data']['hash']) server_iv = base64.b64decode(msg_json['sa-data']['iv']) server_random = base64.b64decode(msg_json['sa-data']['random']) new_master_secret = keys.generate_master_secret(public_key, self.new_private_key) new_final_master_secret = keys.generate_final_master_secret(new_master_secret,self.rand_client + server_random) client_hash = keys.message_authentication(self.cipher_suite, new_final_master_secret, ciphertext) self.server_public_key = public_key self.rand_srv = server_random msg_json['payload'] = keys.decrypt(self.cipher_suite,new_final_master_secret,ciphertext,server_iv) if (server_hash != client_hash): logging.warning('Client Hash and Server Hash do not match!') if msg_json['payload']['type'] == 'list': self.receive_list_clients(msg_json['payload'], self.id) elif msg_json['payload']['type'] == 'client-connect': self.receive_client_connect(msg_json['payload']) elif msg_json['payload']['type'] == 'client-disconnect': self.receive_client_disconnect(msg_json['payload']) elif msg_json['payload']['type'] == 'client-com': self.receive_client_com(msg_json['payload']) elif msg_json['payload']['type'] == 'ack': self.receive_client_ack(msg_json['payload'])
def send_client_com(self,dst,cleartext): """ Process a client-com message from client """ msg = {'type':'client-com', 'src': self.id,'dst': dst, 'data': {}} # Client in session client = self.clients[str(dst)] # Cipher: new private key + old public key new_public_key, new_private_key = keys.verify_cipher_suite(client.cipher_suite) client.client_client_master_secret = keys.generate_master_secret(client.received_public_key, new_private_key) tmp_random = os.urandom(32) client.client_client_final_master = keys.generate_final_master_secret(client.client_client_master_secret,client.received_random + tmp_random) ciphertext ,iv = keys.encrypt(client.cipher_suite,client.client_client_final_master ,cleartext) client.digest = keys.message_authentication(client.cipher_suite, client.client_client_final_master, ciphertext) msg['data'] = {'hash':base64.b64encode(client.digest), 'iv' : base64.b64encode(iv), 'public_key': new_public_key, 'ciphertext': base64.b64encode(ciphertext), 'random': base64.b64encode(tmp_random) } # Assinar toda a mensagem signature = keys.signClient(self.session, self.obj[0], json.dumps(msg,sort_keys = True)) msg['sign'] = base64.b64encode(signature) Hash = keys.hash(msg) self.dst_val[Hash] = msg.copy() self.secure_send(msg)
def processSecure(self, sender, request): """ Process a secure message from a client """ if sender.state != STATE_CONNECTED: logging.warning("SECURE from disconnected client: %s" % sender) return if 'payload' not in request: logging.warning("Secure message with missing fields") return # This is a secure message. # TODO: Inner message is encrypted for us. Must decrypt and validate. ciphertext = base64.b64decode(request['payload']['ciphertext']) sender.received_public_key = keys.deserialize_public_key( base64.b64decode(request['payload']['public_key'])) client_hash = base64.b64decode(request['sa-data']['hash']) client_iv = base64.b64decode(request['sa-data']['iv']) sender.random_client = base64.b64decode(request['sa-data']['random']) new_master_secret = keys.generate_master_secret( sender.received_public_key, sender.private_key) sender.final_master_secret = keys.generate_final_master_secret( new_master_secret, sender.random_client + sender.rand_server) server_hash = keys.message_authentication(sender.cipher_suite, sender.final_master_secret, ciphertext) if (client_hash != server_hash): logging.warning('Client Hash and Server Hash do not match!') request['payload'] = keys.decrypt(sender.cipher_suite, sender.final_master_secret, ciphertext, client_iv) if 'type' not in request['payload'].keys(): logging.warning("Secure message without inner frame type") return if request['payload']['type'] == 'list': self.processList(sender, request['payload']) return if not all(k in request['payload'].keys() for k in ("src", "dst")): return if not int(request['payload']['dst']) in self.id2client.keys(): logging.warning("Message to unknown client: %s" % request['payload']['dst']) return dst = self.id2client[int(request['payload']['dst'])] dst_message = {'type': 'secure', 'payload': request['payload']} dst.send(dst_message)
def secure_send(self, msg_json): """ Process a secure message from server """ # Cipher: new private key + old public key msg = {'type': 'secure', 'sa-data':{}, 'payload':{}} new_public_key, self.new_private_key = keys.verify_cipher_suite(self.cipher_suite) new_master_secret = keys.generate_master_secret(self.server_public_key, self.new_private_key) self.rand_client = os.urandom(32) new_final_master_secret = keys.generate_final_master_secret(new_master_secret, self.rand_client + self.rand_srv) ciphertext , client_iv = keys.encrypt(self.cipher_suite,new_final_master_secret,msg_json) msg['sa-data'] = {'hash': base64.b64encode(keys.message_authentication(self.cipher_suite, new_final_master_secret, ciphertext)), 'iv': base64.b64encode(client_iv), 'random':base64.b64encode(self.rand_client)} msg['payload'] = {'ciphertext': base64.b64encode(ciphertext),'public_key': new_public_key} self.sock.send(msg)
def send(self, obj): """Send an object to this client. """ try: tmp = obj.copy() if obj['type'] == 'secure': new_public_key, new_private_key = keys.verify_cipher_suite( self.cipher_suite) #print type(self.received_public_key) new_master_secret = keys.generate_master_secret( self.received_public_key, new_private_key) tmp_rand_server = os.urandom(32) self.final_master_secret = keys.generate_final_master_secret( new_master_secret, self.rand_client + tmp_rand_server) ciphertext, server_iv = keys.encrypt(self.cipher_suite, self.final_master_secret, obj['payload']) obj['payload'] = { 'ciphertext': base64.b64encode(ciphertext), 'public_key': new_public_key } server_hash = keys.message_authentication( self.cipher_suite, self.final_master_secret, ciphertext) obj['sa-data'] = { 'hash': base64.b64encode(server_hash), 'iv': base64.b64encode(server_iv), 'random': base64.b64encode(tmp_rand_server) } # Assinatura serversign = keys.signServer(serverKey, json.dumps(obj, sort_keys=True)) obj['sign'] = base64.b64encode(serversign) if 'ack' not in tmp['payload']['type']: #print 'TMP' Hash = keys.hash(obj) dst_val[Hash] = obj.copy() self.bufout += json.dumps(obj) + "\n\n" else: self.bufout += json.dumps(obj) + "\n\n" except: # It should never happen! And not be reported to the client! logging.exception("Client.send(%s)", self)
def secure_send(self, msg_json): """ Process a secure message from server """ # Cipher: new private key + old public key msg = {'type': 'secure', 'sa-data':{}, 'payload':{} } new_public_key, new_private_key = keys.verify_cipher_suite(self.cipher_suite) new_master_secret = keys.generate_master_secret(self.server_public_key, new_private_key) tmp_rand_client = os.urandom(32) new_final_master_secret = keys.generate_final_master_secret(new_master_secret, self.rand_srv + tmp_rand_client) ciphertext , client_iv = keys.encrypt(self.cipher_suite,new_final_master_secret,msg_json) msg['sa-data'] = {'hash': base64.b64encode(keys.message_authentication(self.cipher_suite, new_final_master_secret, ciphertext)), 'iv': base64.b64encode(client_iv), 'random':base64.b64encode(tmp_rand_client)} msg['payload'] = {'ciphertext': base64.b64encode(ciphertext),'public_key': new_public_key} # assinar toda a msg signature = keys.signClient(self.session, self.obj[0], json.dumps(msg,sort_keys = True)) msg['sign'] = base64.b64encode(signature) if 'src' in msg_json.keys() and msg_json['type'] != 'ack': h = keys.hash(msg_json) self.dst_val[h] = msg_json #save secure msg Hash = keys.hash(msg) self.dst_val[Hash] = msg.copy() self.sock.send(msg) return #save secure msg Hash = keys.hash(msg) self.dst_val[Hash] = msg.copy() self.sock.send(msg) return
def receive_client_com(self,reply): """ Process a client-com message from client """ # Client in session client = self.clients[str(reply['src'])] # get client sign sign = base64.b64decode(reply['sign']) del reply['sign'] #validation if keys.verifySign(sign, client.cert, json.dumps(reply,sort_keys=True)) == False: logging.warning("Invalid Signature!!") return # CONTINUE # CONA # Decipher: public key received + old private key ciphertext = base64.b64decode(reply['data']['ciphertext']) tmp_public_key = keys.deserialize_public_key(base64.b64decode(reply['data']['public_key'])) digest = base64.b64decode(reply['data']['hash']) tmp_received_random = base64.b64decode(reply['data']['random']) iv = base64.b64decode(reply['data']['iv']) client.client_client_master_secret = keys.generate_master_secret(tmp_public_key, client.private_key) client.client_client_final_master = keys.generate_final_master_secret(client.client_client_master_secret, client.random + tmp_received_random) client.digest = keys.message_authentication(client.cipher_suite,client.client_client_final_master, ciphertext) if client.digest != digest: logging.warning('Client Hash and Server Hash do not match!') cleartext = keys.decrypt(client.cipher_suite, client.client_client_final_master, ciphertext, iv) print '__________________________________________\n' print 'Client:',str(reply['src']),'# ',cleartext print '__________________________________________\n'
def processConnect(self, sender, request): """ Process a connect message from a client """ if sender.state == STATE_CONNECTED: logging.warning("Client is already connected: %s" % sender) return if not all(k in request.keys() for k in ("name", "ciphers", "phase", "id")): logging.warning("Connect message with missing fields") return msg = { 'type': 'connect', 'phase': request['phase'] + 1, 'ciphers': ['NONE'] } if len(request['ciphers']) > 1 or 'NONE' not in request['ciphers']: logging.info("Connect continue to phase " + str(msg['phase'])) # Server ciphers msg['ciphers'] = [ 'ECDHE-AES128_CTR-SHA256', 'DHE-AES128_CTR-SHA256', 'ECDHE-AES256_CTR-SHA384' ] #begin ECDHE handshake # Cipher_suite selection mode for c in msg['ciphers']: if c in request['ciphers']: sender.cipher_suite = c break if sender.cipher_suite == None: logging.warning('\nCipher Spec not supported!') return msg['ciphers'] = sender.cipher_suite msg['data'] = {} public_key, sender.private_key = keys.verify_cipher_suite( sender.cipher_suite) if request['phase'] == 3: # deserialize client public key peer_public_key = keys.deserialize_public_key( base64.b64decode(request['data']['public_key'])) # generate master secret self.master_secret = keys.generate_master_secret( peer_public_key, sender.private_key) #print type(self.master_secret ) # server random sender.rand_server = os.urandom(32) # get client random rand_client = base64.b64decode( request['data']['client_random']) msg['data'] = { 'public_key': public_key, 'server_random': base64.b64encode(sender.rand_server) } # generate final master key(master_key, rand_client+rand_server) sender.final_master_secret = keys.generate_final_master_secret( self.master_secret, rand_client + sender.rand_server) session_connected = True if session_connected: #print type(request['id']) self.id2client[int(request['id'])] = sender sender.id = request['id'] sender.name = request['name'] sender.state = STATE_CONNECTED logging.info("Client %s Connected" % request['id']) sender.send(msg)
def receive_client_connect(self, reply): """ Process a client-connect message from client (phase > 1) """ msg = {'type':'client-connect'} if reply['phase'] == 1: self.addClient(str(reply['src'])) client= self.clients[str(reply['src'])] if str(reply['src']) not in self.clients: logging.warning('Client not supported!') ciphers = ['ECDHE-RSA-CTR-SHA256', 'ECDHE-AES256_CTR-SHA384','ECDHE-AES128_CTR-SHA256'] # Cipher_suite selection mode cipher = [c for c in reply['ciphers'] if c in ciphers] if cipher == []: logging.warning('Does not support cipher spec!') return msg['src'] = reply['dst'] msg['dst'] = reply['src'] msg['phase'] = reply['phase']+1 msg['ciphers'] = cipher[0] client.cipher_suite = msg['ciphers'] msg['data'] = {} self.secure_send(msg) return if reply['phase'] == 2: client = self.clients[str(reply['src'])] if reply['ciphers'] not in client.cipher_suite: logging.warning('Does not support cipher spec!') return client.cipher_suite = reply['ciphers'] client.public_key, client.private_key = keys.verify_cipher_suite(client.cipher_suite) client.random = os.urandom(32) msg['data'] = {'public_key': client.public_key, 'random': base64.b64encode(client.random)} msg['dst'] = reply['src'] msg['src'] = reply['dst'] msg['phase'] = reply['phase']+1 msg['ciphers'] = reply['ciphers'] self.secure_send(msg) return if reply['phase'] == 3: client = self.clients[str(reply['src'])] client.cipher_suite = reply['ciphers'] client.public_key, client.private_key = keys.verify_cipher_suite(client.cipher_suite) client.random = os.urandom(32) client.received_public_key = keys.deserialize_public_key(base64.b64decode(reply['data']['public_key'])) client.received_random = base64.b64decode(reply['data']['random']) client.client_client_master_secret = keys.generate_master_secret(client.received_public_key,client.private_key) client.client_client_final_master = keys.generate_final_master_secret(client.client_client_master_secret,client.received_random+client.random) msg['data'] = {'public_key': client.public_key, 'random':base64.b64encode(client.random)} msg['dst'] = reply['src'] msg['src'] = reply['dst'] msg['phase'] = reply['phase'] +1 self.secure_send(msg) return if reply['phase'] == 4: client = self.clients[str(reply['src'])] client.received_public_key = keys.deserialize_public_key(base64.b64decode(reply['data']['public_key'])) client.client_client_master_secret = keys.generate_master_secret(client.received_public_key,client.private_key ) client.received_random = base64.b64decode(reply['data']['random']) client.client_client_final_master = keys.generate_final_master_secret(client.client_client_master_secret,client.random+client.received_random ) print 'Connection to the Client finished with sucess!\n' return
def processConnect(self, sender, request): """ Process a connect message from a client """ if sender.state == STATE_CONNECTED: logging.warning("Client is already connected: %s" % sender) return if not all(k in request.keys() for k in ("name", "ciphers", "phase", "id")): logging.warning("Connect message with missing fields") return msg = { 'type': 'connect', 'phase': request['phase'] + 1, 'ciphers': ['NONE'] } if len(request['ciphers']) > 1 or 'NONE' not in request['ciphers']: logging.info("Connect continue to phase " + str(msg['phase'])) # Server ciphers msg['ciphers'] = [ 'ECDHE-AES128_CTR-SHA256', 'DHE-AES128_CTR-SHA256', 'ECDHE-AES256_CTR-SHA384' ] #begin ECDHE handshake if request['phase'] == 1: Hash = keys.hash(request) ack = {'type': 'ack', 'hash': Hash} sender.send(ack) # Identity Preservation if len(self.certificates.keys()) > 0: for k, v in self.certificates.iteritems(): if v == base64.b64decode( request['data']['certificate']): logging.error("Certificado em uso!") self.delClient(sender.socket) sender.close() return #get client cert sender.cert = base64.b64decode(request['data']['certificate']) #cert verificate cert = openssl.load_certificate(openssl.FILETYPE_ASN1, sender.cert) if keys.verifycert(cert, store) == False: logging.warning("Invalid Certificate!!") self.delClient(sender.socket) sender.close() return # Cipher_suite selection mode for c in msg['ciphers']: if c in request['ciphers']: sender.cipher_suite = c break if sender.cipher_suite == None: logging.warning('\nCipher Spec not supported!') return msg['ciphers'] = sender.cipher_suite self.serverRandom = os.urandom(32) msg['data'] = { 'certificate': base64.b64encode(serverCert), 'challenge': base64.b64encode(self.serverRandom) } if request['phase'] == 3: Hash = keys.hash(request) ack = {'type': 'ack', 'hash': Hash} sender.send(ack) sign = base64.b64decode(request['data']['sign_challenge']) self.randomClient = base64.b64decode( request['data']['challenge']) #validation if keys.verifySign(sign, sender.cert, self.serverRandom) == False: logging.warning("Invalid Signature!!") self.delClient(sender.socket) sender.close() return sign_randClient = keys.signServer(serverKey, self.randomClient) msg['data'] = { 'sign_challenge': base64.b64encode(sign_randClient) } # Server Keys public_key, sender.private_key = keys.verify_cipher_suite( sender.cipher_suite) if request['phase'] == 5: Hash = keys.hash(request) ack = {'type': 'ack', 'hash': Hash} sign_ack = keys.signServer(serverKey, json.dumps(ack, sort_keys=True)) ack['sign'] = base64.b64encode(sign_ack) sender.send(ack) sign = base64.b64decode(request['sign']) del request['sign'] #validation if keys.verifySign(sign, sender.cert, json.dumps(request, sort_keys=True)) == False: logging.warning("Invalid Signature!!") self.delClient(sender.socket) sender.close() return # deserialize client public key sender.received_public_key = keys.deserialize_public_key( base64.b64decode(request['data']['public_key'])) # generate master secret self.master_secret = keys.generate_master_secret( sender.received_public_key, sender.private_key) #print type(self.master_secret ) # server random sender.rand_server = os.urandom(32) # get client random sender.rand_client = base64.b64decode( request['data']['client_random']) msg['data'] = { 'public_key': public_key, 'server_random': base64.b64encode(sender.rand_server) } # sign all msg with serverkey serversign = keys.signServer(serverKey, json.dumps(msg, sort_keys=True)) msg['sign'] = base64.b64encode(serversign) # generate final master key(master_key, rand_client+rand_server) sender.final_master_secret = keys.generate_final_master_secret( self.master_secret, sender.rand_client + sender.rand_server) session_connected = True if session_connected: #print type(request['id']) self.id2client[int(request['id'])] = sender sender.id = request['id'] sender.name = request['name'] sender.state = STATE_CONNECTED logging.info("Client %s Connected" % request['id']) # Identity Preservation self.certificates[int(request['id'])] = sender.cert # Bell self.bell[sender.id] = self.id2client[int(sender.id)].level print "\n\n" Hash = keys.hash(msg) dst_val[Hash] = msg.copy() #print '\nHASH',base64.b64encode(Hash) #print '\nMSG', msg sender.send(msg)
def receive_client_connect(self, reply): """ Process a client-connect message from client (phase > 1) """ msg = {'type':'client-connect'} if reply['phase'] == 1: Hash = keys.hash(reply) ack = {'type':'ack','hash':Hash, 'src': self.id, 'dst': reply['src']} self.secure_send(ack) #get peer_client cert cli_cert = base64.b64decode(reply['data']['certificate']) #cert verification cert = openssl.load_certificate(openssl.FILETYPE_ASN1, cli_cert) if keys.verifycert(cert,self.store) == False: logging.warning("Invalid Certificate!!") return self.addClient(str(reply['src'])) client= self.clients[str(reply['src'])] if str(reply['src']) not in self.clients: logging.warning('Client not supported!') ciphers = ['ECDHE-RSA-CTR-SHA256', 'ECDHE-AES256_CTR-SHA384','ECDHE-AES128_CTR-SHA256'] # Cipher_suite selection mode cipher = [c for c in reply['ciphers'] if c in ciphers] if cipher == []: logging.warning('Does not support cipher spec!') return msg['src'] = reply['dst'] msg['dst'] = reply['src'] msg['phase'] = reply['phase']+1 msg['ciphers'] = cipher[0] # Update client.cipher_suite = msg['ciphers'] client.cert = cli_cert client.randomCH = os.urandom(32) msg['data'] = {'certificate': base64.b64encode(self.cert),'challenge':base64.b64encode(client.randomCH)} Hash = keys.hash(msg) self.dst_val[Hash] = msg.copy() self.secure_send(msg) return if reply['phase'] == 2: Hash = keys.hash(reply) ack = {'type':'ack','hash':Hash, 'src': self.id, 'dst': reply['src']} self.secure_send(ack) #get peer_client cert cli_cert = base64.b64decode(reply['data']['certificate']) #cert verification cert = openssl.load_certificate(openssl.FILETYPE_ASN1,cli_cert) if keys.verifycert(cert,self.store) == False: logging.warning("Invalid Certificate!!") return client = self.clients[str(reply['src'])] if reply['ciphers'] not in client.cipher_suite: logging.warning('Does not support cipher spec!') return # Update client.cipher_suite = reply['ciphers'] client.cert = cli_cert peerRandom = base64.b64decode(reply['data']['challenge']) client.randomCH = os.urandom(32) sign_peerRandom = keys.signClient(self.session, self.obj[0], peerRandom) msg['dst'] = reply['src'] msg['src'] = reply['dst'] msg['phase'] = reply['phase'] +1 msg['ciphers'] = reply['ciphers'] msg['data'] = {'sign_challenge':base64.b64encode(sign_peerRandom),'challenge':base64.b64encode(client.randomCH)} Hash = keys.hash(msg) self.dst_val[Hash] = msg.copy() self.secure_send(msg) return if reply['phase'] == 3: Hash = keys.hash(reply) ack = {'type':'ack','hash':Hash, 'src': self.id, 'dst': reply['src']} self.secure_send(ack) client = self.clients[str(reply['src'])] # get client sign sign = base64.b64decode(reply['data']['sign_challenge']) #validation if keys.verifySign(sign, client.cert, client.randomCH)== False: logging.warning("Invalid Signature!!") return peerRandom = base64.b64decode(reply['data']['challenge']) sign_peerRandom = keys.signClient(self.session, self.obj[0], peerRandom) msg['data'] = {'sign_challenge':base64.b64encode(sign_peerRandom)} client.cipher_suite = reply['ciphers'] msg['dst'] = reply['src'] msg['src'] = reply['dst'] msg['phase'] = reply['phase'] +1 Hash = keys.hash(msg) self.dst_val[Hash] = msg.copy() self.secure_send(msg) return if reply['phase'] == 4: Hash = keys.hash(reply) ack = {'type':'ack','hash':Hash, 'src': self.id, 'dst': reply['src']} self.secure_send(ack) client = self.clients[str(reply['src'])] # get client sign sign = base64.b64decode(reply['data']['sign_challenge']) #validation if keys.verifySign(sign, client.cert, client.randomCH) == False: logging.warning("Invalid Signature!!") return print "\n\n" print "Challenge Response Complete!!" print "\n\n" client.public_key, client.private_key = keys.verify_cipher_suite(client.cipher_suite) client.random = os.urandom(32) msg['data'] = {'public_key': client.public_key, 'random': base64.b64encode(client.random)} msg['dst'] = reply['src'] msg['src'] = reply['dst'] msg['phase'] = reply['phase']+1 #msg['ciphers'] = reply['ciphers'] # Assinar toda a mensagem signature = keys.signClient(self.session, self.obj[0], json.dumps(msg,sort_keys = True)) msg['sign'] = base64.b64encode(signature) Hash = keys.hash(msg) self.dst_val[Hash] = msg.copy() self.secure_send(msg) return if reply['phase'] == 5: Hash = keys.hash(reply) ack = {'type':'ack','hash':Hash, 'src': self.id, 'dst': reply['src']} sign_ack = keys.signClient(self.session, self.obj[0], json.dumps(ack,sort_keys = True)) ack['sign'] = base64.b64encode(sign_ack) self.secure_send(ack) client = self.clients[str(reply['src'])] # get client sign sign = base64.b64decode(reply['sign']) del reply['sign'] #validation if keys.verifySign(sign, client.cert, json.dumps(reply,sort_keys=True)) == False: logging.warning("Invalid Signature!!") return # CONTINUE #client.cipher_suite = reply['ciphers'] client.public_key, client.private_key = keys.verify_cipher_suite(client.cipher_suite) client.random = os.urandom(32) client.received_public_key = keys.deserialize_public_key(base64.b64decode(reply['data']['public_key'])) client.received_random = base64.b64decode(reply['data']['random']) client.client_client_master_secret = keys.generate_master_secret(client.received_public_key,client.private_key) client.client_client_final_master = keys.generate_final_master_secret(client.client_client_master_secret,client.received_random+client.random) msg['data'] = {'public_key': client.public_key, 'random':base64.b64encode(client.random)} msg['dst'] = reply['src'] msg['src'] = reply['dst'] msg['phase'] = reply['phase'] +1 # enviar info do Hardware info_hash = keys.participantConsistency_Hash() info = keys.participantConsistency() # cifrar info do Hardware tmp = { 'hash': info_hash, 'info':info} encrypt_info, iv = keys.encrypt(client.cipher_suite, client.client_client_final_master, tmp ) msg['encrypt_hardware'] ={ 'encrypt_info':base64.b64encode(encrypt_info) , 'iv': base64.b64encode(iv)} # Assinar toda a mensagem signature = keys.signClient(self.session, self.obj[0], json.dumps(msg,sort_keys = True)) msg['sign'] = base64.b64encode(signature) Hash = keys.hash(msg) self.dst_val[Hash] = msg.copy() self.secure_send(msg) return if reply['phase'] == 6: Hash = keys.hash(reply) ack = {'type':'ack','hash':Hash, 'src': self.id, 'dst': reply['src']} sign_ack = keys.signClient(self.session, self.obj[0], json.dumps(ack,sort_keys = True)) ack['sign'] = base64.b64encode(sign_ack) self.secure_send(ack) client = self.clients[str(reply['src'])] # get client sign sign = base64.b64decode(reply['sign']) del reply['sign'] #validation if keys.verifySign(sign, client.cert, json.dumps(reply,sort_keys=True)) == False: logging.warning("Invalid Signature!!") return # CONTINUE client.received_public_key = keys.deserialize_public_key(base64.b64decode(reply['data']['public_key'])) client.client_client_master_secret = keys.generate_master_secret(client.received_public_key,client.private_key ) client.received_random = base64.b64decode(reply['data']['random']) client.client_client_final_master = keys.generate_final_master_secret(client.client_client_master_secret,client.random+client.received_random ) to_decrypt = base64.b64decode(reply['encrypt_hardware']['encrypt_info']) iv_todecrypt = base64.b64decode(reply['encrypt_hardware']['iv']) cleartext = keys.decrypt(client.cipher_suite , client.client_client_final_master, to_decrypt ,iv_todecrypt) if client.cert in self.part_cons.keys(): if self.part_cons[client.cert] != (cleartext['hash'][1], cleartext['info'][1]): print 'Hard novo!' print '\n Mac Adrress'+ str(cleartext['info']['brand']) # Update self.part_cons[client.cert] = (cleartext['hash'][1], cleartext['info'][1]) print 'Connection to the Client finished with sucess!\n' return
def secure_receive(self, msg_json): """ Process a secure message from server """ # verificar a assinatura antes de fazer o decrypt7 tmp = msg_json.copy() sign = base64.b64decode(msg_json['sign']) del msg_json['sign'] #validation if keys.verifySign(sign, self.servercert, json.dumps(msg_json,sort_keys=True)) == False: logging.warning("Invalid Signature!!") return # CONTINUE # CONA # Decipher: public key received + old private key ciphertext = base64.b64decode(msg_json['payload']['ciphertext']) public_key = keys.deserialize_public_key(base64.b64decode(msg_json['payload']['public_key'])) server_hash = base64.b64decode(msg_json['sa-data']['hash']) server_iv = base64.b64decode(msg_json['sa-data']['iv']) server_random = base64.b64decode(msg_json['sa-data']['random']) new_master_secret = keys.generate_master_secret(public_key, self.private_key) new_final_master_secret = keys.generate_final_master_secret(new_master_secret,self.rand_client + server_random) client_hash = keys.message_authentication(self.cipher_suite, new_final_master_secret, ciphertext) msg_json['payload'] = keys.decrypt(self.cipher_suite,new_final_master_secret,ciphertext,server_iv) #print '\nPayloadSecure' #print msg_json['payload'] if (server_hash != client_hash): logging.warning('Client Hash and Server Hash do not match!') if msg_json['payload']['type'] == 'ack': self.receive_ack(msg_json['payload']) return Hash = keys.hash(tmp) ack = {'type':'ack','hash':Hash} sign_ack = keys.signClient(self.session, self.obj[0], json.dumps(ack,sort_keys = True)) ack['sign'] = base64.b64encode(sign_ack) self.secure_send(ack) if msg_json['payload']['type'] == 'list': self.receive_list_clients(msg_json['payload'], self.id) return if msg_json['payload']['type'] == 'client-connect': self.receive_client_connect(msg_json['payload']) return if msg_json['payload']['type'] == 'client-disconnect': self.receive_client_disconnect(msg_json['payload']) return #print '123456' #print msg_json['payload'] Hash = keys.hash(msg_json['payload']) ack = {'type':'ack', 'hash':Hash, 'src': self.id, 'dst': msg_json['payload']['src']} sign_ack = keys.signClient(self.session, self.obj[0], json.dumps(ack,sort_keys = True)) ack['sign'] = base64.b64encode(sign_ack) self.secure_send(ack) if msg_json['payload']['type'] == 'client-com': self.receive_client_com(msg_json['payload'])
def connect_receive(self, reply=None): """ Process a connect message from server (phase > 1)""" msg = {'type': 'connect', 'phase': reply['phase']+1, 'name': self.name, 'id': self.id, 'ciphers': ['NONE'], 'data': {}} #print "\n\n" #print reply if reply['phase'] == 2: Hash = keys.hash(reply) ack = {'type':'ack','hash':Hash} self.sock.send(ack) self.servercert = base64.b64decode(reply['data']['certificate']) #cert verificate cert = openssl.load_certificate(openssl.FILETYPE_ASN1, self.servercert) if keys.verifycert(cert,self.storeServer,True) == False: logging.warning("Invalid Certificate!!") return self.cipher_suite = reply['ciphers'] msg['ciphers'] = reply['ciphers'] self.clientRandom = os.urandom(32) self.randomServer = base64.b64decode(reply['data']['challenge']) sign_randServer = keys.signClient(self.session, self.obj[0], self.randomServer) msg['data'] = {'sign_challenge': base64.b64encode(sign_randServer), 'challenge':base64.b64encode(self.clientRandom)} if reply['phase'] == 4: Hash = keys.hash(reply) ack = {'type':'ack','hash':Hash} self.sock.send(ack) sign = base64.b64decode(reply['data']['sign_challenge']) #validation if keys.verifySign(sign, self.servercert,self.clientRandom ) == False: logging.warning("Invalid Signature!!") return print "\n\n" print "Challenge Response Complete!!" print "\n\n" # keys pair creation self.public_key, self.private_key = keys.verify_cipher_suite(self.cipher_suite) msg['ciphers'] = reply['ciphers'] # client random self.rand_client = os.urandom(32) msg['data'] = {'public_key': self.public_key, 'client_random': base64.b64encode(self.rand_client)} # assinar toda a msg signature = keys.signClient(self.session, self.obj[0], json.dumps(msg,sort_keys = True)) msg['sign'] = base64.b64encode(signature) if reply['phase'] == 6: Hash = keys.hash(reply) ack = {'type':'ack','hash':Hash} sign_ack = keys.signClient(self.session, self.obj[0], json.dumps(ack,sort_keys = True)) ack['sign'] = base64.b64encode(sign_ack) self.sock.send(ack) sign = base64.b64decode(reply['sign']) del reply['sign'] #validation if keys.verifySign(sign, self.servercert, json.dumps(reply,sort_keys=True)) == False: logging.warning("Invalid Signature!!") return self.server_public_key = keys.deserialize_public_key(base64.b64decode(reply['data']['public_key'])) self.master_secret = keys.generate_master_secret(self.server_public_key, self.private_key) # get random server self.rand_srv = base64.b64decode(reply['data']['server_random']) self.final_master_secret = keys.generate_final_master_secret(self.master_secret, self.rand_client + self.rand_srv) # get server sign # Make the secret secure session_connected = True # print '-------------------------------------------\nServer-Client Handshake completed!!\n-------------------------------------------' if session_connected: print '-------------------------------------------\nBegin Client-Connect!!\n-------------------------------------------' # Automatic list of clients list self.list_clients() print '\n',self.need_help() return Hash = keys.hash(msg) self.dst_val[Hash] = msg.copy() self.sock.send(msg)
def processSecure(self, sender, request): """ Process a secure message from a client """ tmp = request.copy() if sender.state != STATE_CONNECTED: logging.warning("SECURE from disconnected client: %s" % sender) return if 'payload' not in request: logging.warning("Secure message with missing fields") return # This is a secure message. # TODO: Inner message is encrypted for us. Must decrypt and validate. # Validar a assinatura no Secure antes de fazer o decrypt sign = base64.b64decode(request['sign']) del request['sign'] #validation if keys.verifySign(sign, sender.cert, json.dumps(request, sort_keys=True)) == False: logging.warning("Invalid Signature!!") self.delClient(sender.socket) sender.close() return # CONTINUE ciphertext = base64.b64decode(request['payload']['ciphertext']) received_public_key = keys.deserialize_public_key( base64.b64decode(request['payload']['public_key'])) client_hash = base64.b64decode(request['sa-data']['hash']) client_iv = base64.b64decode(request['sa-data']['iv']) tmp_random_client = base64.b64decode(request['sa-data']['random']) new_master_secret = keys.generate_master_secret( received_public_key, sender.private_key) sender.final_master_secret = keys.generate_final_master_secret( new_master_secret, sender.rand_server + tmp_random_client) server_hash = keys.message_authentication(sender.cipher_suite, sender.final_master_secret, ciphertext) if (client_hash != server_hash): logging.warning('Client Hash and Server Hash do not match!') request['payload'] = keys.decrypt(sender.cipher_suite, sender.final_master_secret, ciphertext, client_iv) print "\n\n" print "payload", request['payload'] if request['payload']['type'] == 'ack' and 'src' not in request[ 'payload'].keys(): if 'sign' in request['payload'].keys(): #print "\nSIGN DO ACK" sign = base64.b64decode(request['payload']['sign']) del request['payload']['sign'] #validation if keys.verifySign( sign, sender.cert, json.dumps(request['payload'], sort_keys=True)) == False: logging.warning("Invalid Signature!!") return try: del dst_val[request['payload']['hash']] except: print "Ack from Unknown src!!!" print dst_val print '\n\n' # generate ack for secure response Hash = keys.hash(tmp) ack = {'type': 'ack', 'hash': Hash} sign_ack = keys.signServer(serverKey, json.dumps(ack, sort_keys=True)) ack['sign'] = base64.b64encode(sign_ack) msg = {'type': 'secure', 'payload': ack} sender.send(msg) if 'type' not in request['payload'].keys(): logging.warning("Secure message without inner frame type") return if request['payload']['type'] == 'list': self.processList(sender, request['payload']) return if not all(k in request['payload'].keys() for k in ("src", "dst")): return if not int(request['payload']['dst']) in self.id2client.keys(): logging.warning("Message to unknown client: %s" % request['payload']['dst']) return #Bell-LaPadula if request['payload']['type'] == 'client-com': #print "Entrou" #print "\n\n" print self.bell src = int(request['payload']['src']) dst = int(request['payload']['dst']) print 'src', src print 'dst', dst print self.bell[src] print self.bell[dst] if self.bell[src] > self.bell[dst]: logging.error('Não tem permissao para enviar a mensagem!') return dst = self.id2client[int(request['payload']['dst'])] dst_message = {'type': 'secure', 'payload': request['payload']} dst.send(dst_message)