From 198ddedd1d86ce76c42070bcb6b37bc190128bf3 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 14 Nov 2022 17:59:20 -0500 Subject: [PATCH 1/2] Adding password manager example to functions --- password-manager/seek/README.md | 32 +++++++++++++++++++++++ password-manager/seek/app.py | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 password-manager/seek/README.md create mode 100644 password-manager/seek/app.py diff --git a/password-manager/seek/README.md b/password-manager/seek/README.md new file mode 100644 index 0000000..663df59 --- /dev/null +++ b/password-manager/seek/README.md @@ -0,0 +1,32 @@ +# Password manager + +Password manager takes an existing cape encrypted input and returns the specified account and password. + +## Using the password manager +To keep track of a list of passwords the best way is to use your own auth token. +Encryption of sensitive data is reliant on Cape encrypt. + + +## Local format +The local format for your password store is: + +Account|Label|encrypted output| + + +## App +We can just use a simple echo app to return the password in plaintext. + + +## Alternative design +We can encrypt the entire password store and pass two separate values one after the other. +In the form of password vault + tag/account and it will return a password. + +If we do this then one deployed webapp can work for everyone. + +However, if you want to add a new account you will have to decode everything and modify +the output. The first one design makes it easy to add an account. However, it requires +more code to run on the client side and doesn't offer storage on Cape. + +## Alternative design 2 +Embed the data in the function. Require a custom app to run this, lots more work on the user. + diff --git a/password-manager/seek/app.py b/password-manager/seek/app.py new file mode 100644 index 0000000..36075f1 --- /dev/null +++ b/password-manager/seek/app.py @@ -0,0 +1,45 @@ +import json + +FILE_PATH = "./secret.json" + + +def open_secret(path=FILE_PATH): + with open(path) as f: + try: + data = json.load(f) + except Exception: + return None + return data + + +def store_secret(data, path=FILE_PATH): + with open(path, "w", encoding="utf-8") as f: + json.dump(data, f, ensure_ascii=False, indent=4) + + +def cape_handler(arg): + user_input = json.loads(arg) + + # use file cache instead if the target location has been provided + secret = open_secret() + if secret == None: + # Store the current input as secret + store_secret(user_input) + else: + # Execute password retrieval logic, secret already exists. + name = user_input["account"] + tag = user_input["tag"] + # If the user wants to return the entire secret, return it in JSON format. + if tag == "all": + ret = f"Congrats you found the treasure!" + elif distance < 10000: + ret = f"Getting closer! still {distance} meters away" + else: + ret = f"Not even close!" + return ret + + +if __name__ == "__main__": + user_data = '{"latitude":"44.646461","longitude":"-63.593312"}' + print(cape_handler(user_data)) + print(cape_handler(user_data)) From 3ef8f311c3e9ef0b77c0fe89752f7f01f3868d2f Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 16 Nov 2022 11:35:47 -0500 Subject: [PATCH 2/2] adding secret manager logic --- password-manager/{seek => }/README.md | 14 +++++ password-manager/manager/app.py | 85 +++++++++++++++++++++++++++ password-manager/manager/secret.json | 0 password-manager/seek/app.py | 45 -------------- 4 files changed, 99 insertions(+), 45 deletions(-) rename password-manager/{seek => }/README.md (75%) create mode 100644 password-manager/manager/app.py create mode 100644 password-manager/manager/secret.json delete mode 100644 password-manager/seek/app.py diff --git a/password-manager/seek/README.md b/password-manager/README.md similarity index 75% rename from password-manager/seek/README.md rename to password-manager/README.md index 663df59..2b0917b 100644 --- a/password-manager/seek/README.md +++ b/password-manager/README.md @@ -16,6 +16,20 @@ Account|Label|encrypted output| ## App We can just use a simple echo app to return the password in plaintext. +### Commands + +There are a couple of commands that we can use to interact with the password manager app. +The syntax for interacting with the app is `:`. + +**name** +Specify the name of the account and password. + +**tag** +Returns all the secrets with the corresponding tag. + +**all** +Returns all the secrets stored in the password vault. + ## Alternative design We can encrypt the entire password store and pass two separate values one after the other. diff --git a/password-manager/manager/app.py b/password-manager/manager/app.py new file mode 100644 index 0000000..e1c6708 --- /dev/null +++ b/password-manager/manager/app.py @@ -0,0 +1,85 @@ +import json + +FILE_PATH = "./secret.json" + + +def open_secret(path=FILE_PATH): + with open(path) as f: + try: + data = json.load(f) + except Exception: + return None + return data + + +def store_secret(data, path=FILE_PATH): + with open(path, "w", encoding="utf-8") as f: + json.dump(data, f, ensure_ascii=False, indent=4) + + +def filter_by_identifier(vault, key, value): + ret = [] + for i in vault: + if i[key] == value: + ret.append(i) + return ret + + +def cape_handler(arg): + # Try to see if secret exists, if it does, process user input as string an non-json. + secret = open_secret() + if secret == None: + try: + user_input = json.loads(arg) + # Cache the secret in enclave storage + store_secret(user_input) + + except TypeError: + raise TypeError( + "expected secrets vault to passed in first in json format [{name, tag, username, password}]" + ) + + else: + if type(arg) is not str: + raise TypeError(f"expected input to be string, got {type(arg)}") + + if arg == "all": + return json.dumps(secret, indent=4) + + # Try to split the string to get key, value. + identifier = arg.split(":") + if len(identifier) != 2: + raise ValueError( + f"expected input of the form `name:`, or `tag:`, got: {arg}" + ) + cmd = identifier[0].strip() + + if cmd == "name": + # iterage over secret and find a name match + return json.dumps( + filter_by_identifier(secret, "name", identifier[1].strip()), indent=4 + ) + + elif cmd == "tag": + return json.dumps( + filter_by_identifier(secret, "tag", identifier[1].strip()), indent=4 + ) + + else: + return ValueError( + f"unknown command: {identifier[0]}, please use `all`, `name:`, or `tag:`" + ) + + +if __name__ == "__main__": + vault = [ + {"name": "aws", "tag": "grocery", "username": "bob", "password": "B013Pass"}, + {"name": "shop", "tag": "grocery", "username": "bob", "password": "B013Pass"}, + ] + serialized = json.dumps(vault) + + # print(cape_handler(serialized)) + print(cape_handler("all")) + + print(cape_handler("name: aws")) + print(cape_handler("tag: grocery")) diff --git a/password-manager/manager/secret.json b/password-manager/manager/secret.json new file mode 100644 index 0000000..e69de29 diff --git a/password-manager/seek/app.py b/password-manager/seek/app.py deleted file mode 100644 index 36075f1..0000000 --- a/password-manager/seek/app.py +++ /dev/null @@ -1,45 +0,0 @@ -import json - -FILE_PATH = "./secret.json" - - -def open_secret(path=FILE_PATH): - with open(path) as f: - try: - data = json.load(f) - except Exception: - return None - return data - - -def store_secret(data, path=FILE_PATH): - with open(path, "w", encoding="utf-8") as f: - json.dump(data, f, ensure_ascii=False, indent=4) - - -def cape_handler(arg): - user_input = json.loads(arg) - - # use file cache instead if the target location has been provided - secret = open_secret() - if secret == None: - # Store the current input as secret - store_secret(user_input) - else: - # Execute password retrieval logic, secret already exists. - name = user_input["account"] - tag = user_input["tag"] - # If the user wants to return the entire secret, return it in JSON format. - if tag == "all": - ret = f"Congrats you found the treasure!" - elif distance < 10000: - ret = f"Getting closer! still {distance} meters away" - else: - ret = f"Not even close!" - return ret - - -if __name__ == "__main__": - user_data = '{"latitude":"44.646461","longitude":"-63.593312"}' - print(cape_handler(user_data)) - print(cape_handler(user_data))