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)
Example #2
0
    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 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)
Example #4
0
    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)
Example #5
0
    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 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)
Example #9
0
    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 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 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 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)