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 send_client_connect(self,dst):
		 """ Process a client-connect message from client (phase = 1) """
		 msg = {'type':'client-connect', 'src': self.id , 'dst': dst, 'phase': 1, 'ciphers': [], 'data': {} }
		 
		 # Client addition for connect
		 self.addClient(dst)
		 # Client added to the clients list
		 client = self.clients[dst]
		 
		 msg['ciphers'] = ['ECDHE-AES128_CTR-SHA256', 'ECDHE-AES256_CTR-SHA384']

		 # send cert
		 msg['data'] = {'certificate':base64.b64encode(self.cert)}

		 # Assinat toda a msg
		 #signature = keys.signClient(self.session, self.obj[0], json.dumps(msg,sort_keys = True))
		 #msg['sign'] = base64.b64encode(signature)

		 # Update
		 client.cipher_suite = msg['ciphers']

		 Hash = keys.hash(msg)
		 self.dst_val[Hash] = msg.copy()

		 self.secure_send(msg)
    def send_client_disconnect(self, dest):
		""" Process a client-disconnect message from aclient """
		msg = {'type': 'client-disconnect', 'src': self.id, 'dst': dest, 'data': {}}
		# 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 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 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 connect_send(self, name, msg = None):
		""" Process a connect message from server (phase = 1) """
		msg = {'type': 'connect', 'phase': 1, 'name': self.name, 'id': self.id, 'ciphers': ['NONE'], 'data': {}}
		  
		print '-------------------------------------------\nBegin Server-Client Handshake\n-------------------------------------------'
		msg['ciphers'] = ['ECDHE-AES128_CTR-SHA256', 'ECDHE-AES256_CTR-SHA384']

		# Assinatura
		#signature = keys.signClient(self.session, self.obj[0], json.dumps(msg,sort_keys = True))
		#msg['sign'] = base64.b64encode(signature)

		msg['data'] = {'certificate':base64.b64encode(self.cert)}

		Hash = keys.hash(msg)
		self.dst_val[Hash] = msg.copy()


		self.sock.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)
    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)