blob: dac68646170c0fd12b11727d422faf7b488ee5f8 [file] [log] [blame]
#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from teaclave import FunctionInput, OwnerList, DataMap
from utils import connect_authentication_service, connect_frontend_service, PlatformAdmin
# In the example, user 0 creates the task and user 0, 1, upload their private data.
# Then user 0 invokes the task and user 0, 1 get the result.
class UserData:
def __init__(self,
user_id,
password,
input_url="",
encryption_algorithm="teaclave-file-128",
input_cmac=[],
iv=[],
key=[]):
self.user_id = user_id
self.password = password
self.input_url = input_url
self.encryption_algorithm = encryption_algorithm
self.input_cmac = input_cmac
self.iv = iv
self.key = key
INPUT_FILE_URL_PREFIX = "http://localhost:6789/fixtures/functions/password_check/"
# Client
USER_DATA_0 = UserData(
"user0",
"password",
"data:text/plain;base64,c+mpvRfZ0fboR0j3rTgOGDBiubSzlCt9", # base64 of encrypted string "password"
"aes-gcm-128",
[
0xe8, 0x47, 0x48, 0xf7, 0xad, 0x38, 0x0e, 0x18, 0x30, 0x62, 0xb9, 0xb4,
0xb3, 0x94, 0x2b, 0x7d
],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
# Data provider
USER_DATA_1 = UserData("user1", "password",
INPUT_FILE_URL_PREFIX + "exposed_passwords.txt.enc",
"teaclave-file-128", [
0xa3, 0x1d, 0xd0, 0xb7, 0xde, 0x0b, 0x6c, 0xc7,
0xe0, 0xde, 0xc1, 0xdc, 0xf7, 0xa4, 0x64, 0x79
], [], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
class Client:
def __init__(self, user_id, user_password):
self.user_id = user_id
self.user_password = user_password
with connect_authentication_service() as client:
print(f"[+] {self.user_id} login")
token = client.user_login(self.user_id, self.user_password)
self.client = connect_frontend_service()
metadata = {"id": self.user_id, "token": token}
self.client.metadata = metadata
def set_task(self):
client = self.client
print(f"[+] {self.user_id} registering function")
function_id = client.register_function(
name="builtin-password-check",
description="Check whether a password is exposed.",
executor_type="builtin",
arguments=[],
inputs=[
FunctionInput("password", "Client 0 data."),
FunctionInput("exposed_passwords", "Client 1 data.")
],
outputs=[])
print(f"[+] {self.user_id} creating task")
task_id = client.create_task(
function_id=function_id,
function_arguments={},
executor="builtin",
inputs_ownership=[
OwnerList("password", [USER_DATA_0.user_id]),
OwnerList("exposed_passwords", [USER_DATA_1.user_id])
],
)
return task_id
def run_task(self, task_id):
client = self.client
print(f"[+] {self.user_id} invoking task")
client.invoke_task(task_id)
def register_data(self, task_id, input_url, algorithm, input_cmac,
file_key, iv, input_label):
client = self.client
print(f"[+] {self.user_id} registering input file")
url = input_url
cmac = input_cmac
schema = algorithm
key = file_key
input_id = client.register_input_file(url, schema, key, iv, cmac)
print(f"[+] {self.user_id} assigning data to task")
client.assign_data_to_task(task_id, [DataMap(input_label, input_id)],
[])
def approve_task(self, task_id):
client = self.client
print(f"[+] {self.user_id} approving task")
client.approve_task(task_id)
def get_task_result(self, task_id):
client = self.client
print(f"[+] {self.user_id} getting task result")
return bytes(client.get_task_result(task_id))
def main():
platform_admin = PlatformAdmin("admin", "teaclave")
try:
platform_admin.register_user(USER_DATA_0.user_id, USER_DATA_0.password)
platform_admin.register_user(USER_DATA_1.user_id, USER_DATA_1.password)
except Exception:
pass
user0 = Client(USER_DATA_0.user_id, USER_DATA_0.password)
user1 = Client(USER_DATA_1.user_id, USER_DATA_1.password)
task_id = user0.set_task()
user0.register_data(
task_id,
USER_DATA_0.input_url,
USER_DATA_0.encryption_algorithm,
USER_DATA_0.input_cmac,
USER_DATA_0.key,
USER_DATA_0.iv,
"password",
)
user1.register_data(
task_id,
USER_DATA_1.input_url,
USER_DATA_1.encryption_algorithm,
USER_DATA_1.input_cmac,
USER_DATA_1.key,
USER_DATA_1.iv,
"exposed_passwords",
)
user0.approve_task(task_id)
user1.approve_task(task_id)
## USER 0 start the computation
user0.run_task(task_id)
## USER 0, 1 get the result
result_user0 = user0.get_task_result(task_id)
result_user1 = user1.get_task_result(task_id)
print("[+] User 0 result: " + result_user0.decode("utf-8"))
print("[+] User 1 result: " + result_user1.decode("utf-8"))
if __name__ == '__main__':
main()