| #!/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() |