-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathread_encrypted.py
More file actions
122 lines (93 loc) · 3.43 KB
/
Copy pathread_encrypted.py
File metadata and controls
122 lines (93 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import os
import sys
import argparse
from getpass import getpass
from base64 import b64decode
from urllib.parse import urlparse
from solidpod_helper import (
gen_master_key,
gen_verify_key,
derive_keys,
decrypt,
parse_ttl,
path_pred,
iv_pred,
verify_key_pred,
indi_key_pred,
inherit_key_pred,
enc_data_pred,
key_version_pred,
salt_pred,
server_path,
)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Process secret and path arguments')
parser.add_argument('filepath', help='File path within data folder')
args = parser.parse_args()
# File path format: server_path/pod_name/app_name/data/data_file
file_path = os.path.abspath(args.filepath)
assert file_path.startswith(server_path)
items = file_path.replace(server_path, '').split('/')
assert len(items) >= 4
pod_name = items[0]
app_name = items[1]
assert items[2] == 'data'
app_path = f'{server_path}{pod_name}/{app_name}'
relative_file_path = '/'.join(items[1:])
security_key_str = getpass(prompt='Security Key: ')
# Verify security key
enc_key_map = parse_ttl(f'{app_path}/encryption/enc-keys.ttl')
enc_key_entry = list(enc_key_map.items())[0][1]
# Derive keys as per solidpod: v2 or legacy
if key_version_pred in enc_key_entry:
assert salt_pred in enc_key_entry
salt = b64decode(enc_key_entry[salt_pred])
master_key, verify_key = derive_keys(security_key_str, salt)
else:
master_key = gen_master_key(security_key_str)
verify_key = gen_verify_key(security_key_str).decode('utf-8')
verify_key_stored = enc_key_entry[verify_key_pred]
if verify_key != verify_key_stored:
print('ERROR: Incorrect security key (verification failed).')
sys.exit(0)
# Parse data .ttl file
with open(file_path) as fd:
file_content = fd.read()
_map = parse_ttl(ttl_str=file_content)
def exit():
print(f'WARN: File "{args.filepath}" is not encrypted by solidpod, return raw content\n{"-"*20}')
print(file_content)
sys.exit(0)
if len(_map) != 1:
exit()
file_url, data_map = list(_map.items())[0]
if (path_pred not in data_map) or (data_map[path_pred] != relative_file_path):
exit()
if (iv_pred not in data_map) or (enc_data_pred not in data_map):
exit()
data_ct = b64decode(data_map[enc_data_pred])
data_iv = b64decode(data_map[iv_pred])
# Retrieve encryption key and IV
key_map = parse_ttl(f'{app_path}/encryption/ind-keys.ttl')
indi_key_ct = None
indi_key_iv = None
if file_url in key_map:
indi_key_ct = b64decode(key_map[file_url][indi_key_pred])
indi_key_iv = b64decode(key_map[file_url][iv_pred])
elif inherit_key_pred in data_map:
r = urlparse(file_url)
server_url = f'{r.scheme}://{r.netloc}'
inherit_key_url = '/'.join([server_url, pod_name, data_map[inherit_key_pred]])
if inherit_key_url in key_map:
indi_key_ct = b64decode(key_map[inherit_key_url][indi_key_pred])
indi_key_iv = b64decode(key_map[inherit_key_url][iv_pred])
else:
pass
if indi_key_ct is None or indi_key_iv is None:
exit()
# Decrypt individual key
indi_key = b64decode(decrypt(indi_key_ct, master_key, indi_key_iv))
# Decrypt data
plain_text = decrypt(data_ct, indi_key, data_iv)
print('-'*20)
print(plain_text)