summaryrefslogtreecommitdiff
path: root/verify.py
blob: a42106d3214e13314aa04d7bddc7b739e794cee6 (plain)
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())