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
|
import argparse
import base64
import fitz
import json
from pathlib import Path
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
from PIL import Image
from pyzbar import pyzbar
def cert(name):
return Path(__file__).absolute().parent / "certs" / name
def verify(qr_code_bytes):
b64, payload = qr_code_bytes.split(b"#", maxsplit=1)
sig = base64.decodebytes(b64)
data = json.loads(payload)
payload = payload.decode().encode("utf8")
if data["ct"] == 1:
digest = payload
for i in range(len(data["p"])):
print(f"Details of person number {i+1}:")
print(f"\tIsraeli ID Number {data['p'][i]['idl']}")
print(f"\tID valid by {data['p'][i]['e']}")
print(f"Cert Unique ID {data['id']}")
elif data["ct"] == 2:
h = hashes.Hash(hashes.SHA256())
h.update(payload)
digest = h.finalize()
print(f"Israeli ID Number {data['idl']}")
print(f"ID valid by {data['e']}")
print(f"Cert Unique ID {data['id']}")
else:
print("Unsupported certificate type")
with open(cert("RamzorQRPubKey.pem"), "rb") as f:
k = serialization.load_pem_public_key(f.read())
k.verify(
sig,
digest,
padding.PKCS1v15(),
hashes.SHA256(),
)
print("Valid signature!")
def read_qr_code(image_path):
return pyzbar.decode(Image.open(image_path))[0].data
def read_pdf(pdf_path):
doc = fitz.open(pdf_path)
for (xref, *_) in doc.get_page_images(0, full=True):
img = fitz.Pixmap(doc, xref)
img.writePNG(f"{xref}.png")
def create_arg_parser():
parser = argparse.ArgumentParser("Green Pass QR code verifier")
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(
"-i",
"--image-path",
type=Path,
help="Path to an image with the QR code",
default=None,
)
group.add_argument(
"-p",
"--pdf-path",
type=Path,
help="Path to PDF file",
default=None,
)
group.add_argument(
"-t",
"--txt-path",
type=Path,
help="Path to decoded QR code textual content",
default=None,
)
return parser
if __name__ == "__main__":
parser = create_arg_parser()
args = parser.parse_args()
if args.image_path:
verify(read_qr_code(args.image_path))
elif args.pdf_path:
read_pdf(args.pdf_path)
elif args.txt_path:
with open(args.txt_path, "rb") as f:
verify(f.read().strip())
|