def sendmessage(): data = request.json # Get the data (sender, recipient, message) check_db() names, groupnames = names_n_group(current_user.name) sender, recipient = data['sender'], secure_filename(data['recipient']) data['destination'] = recipient # We make a copy for ourself new_message = Message(owner=sender, sender=sender, content=data['content'], time=datetime.now(), recipient=recipient) add_db(new_message, 'Message') # Key is different if it's a group message # or 2-party message if recipient in groupnames: key = get_key_aes(sender, recipient) elif recipient in names: key, dico = P2Psecret(sender, recipient, 'sender') data['info_otk'] = repr(dico) else: raise Exception("Problem : the recipient name : {}".format(recipient)) # Ciphertext encrypted_data = encrypt_aes(data['content'], str(key)) data['content'] = repr(encrypted_data) headers = {'x-access-tokens': get_token(current_user.name)} requests.post(server_address + "/mailbox", json=data, headers=headers) return jsonify(answer="Génial")
def P2Psecret(user, partner, side, public_key=None, method="sike27"): if side == "sender": private_otk = random.randint(1, 2**eA) headers = {'x-access-tokens': get_token(current_user.name)} otk_bundle = requests.get(server_address + "/getOTK/" + partner + "/" + str(-1), headers=headers).json() if method == "sike27": public_otk = convert_Complex( ast.literal_eval(otk_bundle['publOTK'])) elif method == "ecdh" or method == "SIKE751": if method == "SIKE751": sleep(0.00487) public_otk = ast.literal_eval(otk_bundle['publOTK']) dico = { 'creatorOTK': SIKE_compute_pk(private_otk, 'initiator'), 'partnerOTK': otk_bundle['indexOTK'] } secret_key = createSS(public_otk, private_otk, 'initiator', method) return secret_key, dico elif side == "receiver": public_key = ast.literal_eval(public_key) pOTK = get_otk(partner, int(public_key['partnerOTK']), delete=True) private_otk = pOTK.privateOTK public_otk = convert_Complex(public_key['creatorOTK']) secret_key = createSS(public_otk, private_otk, 'receiver', method) return secret_key
def fill_nodes_creator(user, node, method="sike27"): # When the leaves' keys were set, we compute the keys # of the parents, based on the children' ones if not node.isLeaf: l_dico = fill_nodes_creator(user, node.children[0], method) r_dico = fill_nodes_creator(user, node.children[1], method) # We take the 'initiator' side, because we take the left key # (choice with no importance, the inverse is possible, since # we know both private keys) secret_key = createSS(node.children[1].public_key, node.children[0].private_key, side='initiator', method=method) deduce_private_key(node, secret_key, is_node=True, method=method) l_dico.update(r_dico) # We mix together the dicts return l_dico # We go down until the leaves, then we compute their shared secret SS # and the corresponding public key, in order to put them in # the attibute of the node else: private_otk = get_otk(user) # Index of the corresponding public key which is on the server ind_private_otk = private_otk.serverID headers = {'x-access-tokens': get_token(current_user.name)} requests.get(server_address + "/lockOTK/" + str(ind_private_otk), headers=headers) response = requests.get(server_address + "/getOTK/" + node.value + "/" + str(-1), headers=headers) public_otk = response.json() OTKeys = { 'privateOTK': str(ind_private_otk), 'publicOTK': public_otk['publOTK'] } compute_leaf_keys(node, user, node.value, OTKeys, 'initiator', method) # creatorOTK : the corresponding public OTK key of the private one used # partner : indicates the public OTK key used from the partner # into the server dico = { node.value: { 'creatorOTK': compute_pk(private_otk.privateOTK, side='initiator', method=method), 'partnerOTK': public_otk['indexOTK'] } } return dico
def decorator(*args, **kwargs): if current_user.is_authenticated: headers = {'x-access-tokens': get_token(current_user.name)} response = requests.get(server_address + "/still_connected", headers=headers) if response.status_code == 401: return redirect(url_for('login')) return f(*args, **kwargs)
def update_key(): data = request.json print('data = ', data) groupname = data["groupname"] if groupname not in names_n_group(current_user.name)[1]: return "Rien à faire ici", 200 # Updating of the tree tree = read_tree(groupname) update_stage_key(tree, data['groupname']) usernode = get_node(tree, data['user']) usernode.update_secret_key(data['secretK']) path = usernode.path fill_nodes(tree, path) write_tree(groupname, tree) members = get_members(groupname) # We don't send to the member who modified, since # they already did it the modifications for themself members.remove(current_user.name) dico = get_pk_path(tree, usernode) headers = {'x-access-tokens': get_token(current_user.name)} for member in members: intel = { 'sender': current_user.name, 'content': repr(dico), 'recipient': member, 'type': 'update_key', 'groupname': groupname } requests.post(server_address + "/intels/" + member, json=intel, headers=headers) print('\nSuccess : key updated') return "Tout de bon", 200
def remove_member(): # It is important to be up to date before removing a member # in order to be sure we get the correct keys check_db() data = request.json # Intels for the already existing members, so that they # get the tree into the server, and adapt theirs groupname = data['groupname'] members = get_members(groupname) headers = {'x-access-tokens': get_token(current_user.name)} group = get_group(groupname) for member in members: dico = {'groupname': groupname, 'member': data['member']} intel = { 'sender': current_user.name, 'content': json.dumps(dico), 'recipient': member, 'type': 'remove_member', 'groupname': groupname } requests.post(server_address + "/intels/" + member, json=intel, headers=headers) members = get_members(groupname) if data['member'] in members: members.remove(data['member']) group.members = ','.join(members) db.session.commit() return "User removed !", 200
def add_member(): check_db() data = request.json groupname, new_member = data['groupname'], data['newmember'] # Get the tree, add a node and get the node tree = read_tree(groupname) add_node(tree, new_member) newnode = get_node(tree, new_member) # We take a random OTK private key, with the corresponding index private_otk = get_otk(current_user.name) ind_private_otk = private_otk.serverID # Creation of the shared key (leaf key) and we put it in the leaf attribute headers = {'x-access-tokens': get_token(current_user.name)} public_otk = requests.get(server_address + "/getOTK/" + new_member + "/" + str(-1), headers=headers).json() otkeys = { 'privateOTK': str(ind_private_otk), 'publicOTK': public_otk['publOTK'] } compute_leaf_keys(newnode, current_user.name, newnode.value, otkeys, 'initiator') # Update the key pairs fill_nodes(tree, newnode.path) members = get_members(groupname) pks = get_pk_path(tree, newnode) publicKeys = get_all_pk(tree) dico = {'groupname': groupname, 'publicKeys': pks, 'newmember': new_member} # Intels for the already existing members headers = {'x-access-tokens': get_token(current_user.name)} for member in members: intel = { 'sender': current_user.name, 'content': repr(dico), 'recipient': member, 'type': data['type'], 'groupname': groupname } requests.post(server_address + "/intels/" + member, json=intel, headers=headers) # We make a copy not to erase our tree central_tree = deepcopy(tree) clear_leaves(central_tree, get_all_value(central_tree)) # Intel for the new member only, # so that they create its tree dico = { 'info_otk': { 'creatorOTK': SIKE_compute_pk(private_otk.privateOTK, 'initiator'), 'partnerOTK': public_otk['indexOTK'] }, 'groupname': groupname, 'members': ','.join(get_value_leaves(tree)), 'publicKeys': repr(publicKeys) } intel = { 'sender': current_user.name, 'content': repr(dico), 'recipient': new_member, 'type': 'creation', 'groupname': groupname } headers = {'x-access-tokens': get_token(current_user.name)} requests.post(server_address + "/intels/" + new_member, json=intel, headers=headers) # Add the new member to the list of members group = get_group(groupname) group.members = group.members + "," + new_member db.session.commit() return "Done", 200