-
Notifications
You must be signed in to change notification settings - Fork 8
/
site.py
130 lines (111 loc) · 3.7 KB
/
site.py
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
122
123
124
125
126
127
128
129
import json
import ctypes
import base64
import signature_c
from bottle import run, post, request, get, SimpleTemplate, static_file
import os
from datetime import datetime as dt
from utils import load_urls_from_yaml
ENCODING = "utf-8"
urls = load_urls_from_yaml()
hostName = urls["site"]["host_name"]
sitePort = urls["site"]["port"]
# Print the page
@get("/")
def racine():
with open("index_site.html", "rb") as index_file:
return SimpleTemplate(index_file.read()).render(urls=urls)
@get('/static/<filename>')
def server_static(filename):
return static_file(filename, root='./static')
@get('/fonts/<filename>')
def server_static(filename):
return static_file(filename, root='./static/fonts')
# Take an age and a validity duration as an input
# Generate the nonce, store it (with age and validity duration), and send it (only the nonce)
@get("/nonce")
def get_nonce():
timestamp = dt.timestamp(dt.now())
required_age = request.query.required_age
validity = request.query.validity
stored = {"required_age": required_age, "validity": int(validity)}
nonce = str(timestamp)
json.dump(stored, open("./challenges/" + nonce, "w"))
return bytes(json.dumps({"nonce": nonce, "required_age": required_age}), ENCODING)
# Checks the signature sent by a trusted party
@post("/verif")
def verif():
# First checks whether the challenge is authentic and valid
message = request.json
nonce = message["nonce"]
signed_age = message["signed_age"]
try:
stored = json.load(open("./challenges/" + nonce, "r"))
required_age = int(stored["required_age"])
validity = float(stored["validity"])
except:
return bytes(json.dumps({"response": "CORRUPTED NONCE"}), ENCODING)
if int(signed_age) != required_age:
return bytes(json.dumps({"response": "CORRUPTED AGE"}), ENCODING)
if dt.timestamp(dt.now()) > float(nonce) + validity:
return bytes(
json.dumps({"response": "THE TOKEN IS NOT VALID ANYMORE"}), ENCODING
)
# Checks whether the party is revokated: site_verify_tk returns 1 if tk is revokated, else 0
chal_buffer = ctypes.create_string_buffer(bytes(nonce + str(signed_age), ENCODING))
is_revoked = 0
revoked_list = message["revoked_list"]
for tk in revoked_list:
is_revoked += signature_c.pbc.site_verify_tk(
chal_buffer,
ctypes.create_string_buffer(base64.b64decode(message["sign"])),
ctypes.create_string_buffer(base64.b64decode(message["g2"])),
ctypes.create_string_buffer(base64.b64decode(tk)),
)
if is_revoked == 1:
return bytes(json.dumps({"response": "REVOKED"}), ENCODING)
# Checks whether the signature matches correctly
arguments = [
"gpk",
"y",
"cert",
"g1",
"g2",
"sign",
"c1",
"c2",
"d1",
"d2",
"p1",
"p11",
"p12",
"p21",
"p22",
"th11",
"th12",
"th21",
"th22",
"g11",
"g12",
"h11",
"h12",
"g21",
"g22",
"h21",
"h22",
]
sign = signature_c.pbc.site_verify_sign(
chal_buffer,
*[
ctypes.create_string_buffer(base64.b64decode(message[key]))
for key in arguments
]
)
if sign == 1:
return bytes(json.dumps({"response": "ACCESS ALLOWED"}), ENCODING)
else:
return bytes(json.dumps({"response": "ERROR IN CHECKING SIGNATURE"}), ENCODING)
# Run the server
if __name__ == "__main__":
print(f'Available on {urls["site"]["url"]} ...')
run(host=hostName, port=sitePort, server='gunicorn', keyfile='authority.key', certfile='authority.pem')