summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2021-12-31 13:49:56 +0200
committerYuval Adam <_@yuv.al>2021-12-31 13:49:56 +0200
commit2af6cc78edd7313da03f29c1dd628481e029a120 (patch)
tree68f3fb99de071407c161311995a9ac91ea13872e
parent44d3607afc3e7b03729b09086f3ecb830dfaff7c (diff)
WIPwip
-rw-r--r--greenpass/tests/test_verifier.py7
-rw-r--r--greenpass/verifier.py95
-rw-r--r--greenpass/verifiers/base.py3
-rw-r--r--greenpass/verifiers/eu.py93
4 files changed, 103 insertions, 95 deletions
diff --git a/greenpass/tests/test_verifier.py b/greenpass/tests/test_verifier.py
index 8d030c3..61f01fe 100644
--- a/greenpass/tests/test_verifier.py
+++ b/greenpass/tests/test_verifier.py
@@ -1,6 +1,7 @@
from pathlib import Path
from ..verifier import GreenPassVerifier
+from ..verifiers.eu import EuroVerifier
SAMPLES_DIR = Path(__file__).parent / "samples"
@@ -9,3 +10,9 @@ def test_ramzor_samples():
assert 1 == 1
# v = GreenPassVerifier.from_pdf(str(SAMPLES_DIR / "CovidCertificate_01.pdf"))
# assert v.verify() is True
+
+
+def test_eu_cert():
+ data = b"HC1:NCFOXN%TSMAHN-H3TK0FWUPKPH1C-C-AH+UC1ROB.S4UOE+I$4QQFG.I5+TO Z0F/8X*G3M9FQH+4JZW49-A3VGNNVR*G0C7PHBO33-IFR7BS7B29BERJGMJ5UN2H30H3FCN+J3FMJ3QBVINOF7Y9BOJJM478UJ:G7H40NQ1:PI0EGO05AZKZ73423ZQT.EJFG37Y4JXITAFG.8H4PSC9EY8IA7BBIZ.CK+GX3E1.BLEELEACI8:NJC19BJCJA9GCHDGSUVB6DJ6SI4OIMEDTJCJKDLEDL9CWZJ$7K+ COCDL%Q:NK%9D$ZJ*DJWP42W5$3UHTP4SE61AQK9:XPX$79GP6GFINOWC51FD$W4SIO9:H12MTNP8EFQJLA-7/:FWKP/HLIJLKNF8JF172LNFPYS+F9XUVM-2DYCYOUG.ICOML2UCNGZ:VXQ3*WU/PMDENLUTG.J7/6RPF8W4LTVFMSM3WHLCV-GY92LDDI:HTYJDA1TWE:8RAEGD50N-9T2"
+ v = EuroVerifier(data)
+ assert v.verify() is True
diff --git a/greenpass/verifier.py b/greenpass/verifier.py
deleted file mode 100644
index b5182e1..0000000
--- a/greenpass/verifier.py
+++ /dev/null
@@ -1,95 +0,0 @@
-import base64
-import fitz
-import json
-
-from io import BytesIO
-from pathlib import Path
-
-from cryptography.hazmat.primitives import hashes, serialization
-from cryptography.hazmat.primitives.asymmetric import padding, ec
-from cryptography.exceptions import InvalidSignature
-from PIL import Image
-from pyzbar import pyzbar
-
-
-class GreenPassVerifier(object):
- def __init__(self, data_bytes):
- self.validate_bytes(data_bytes)
-
- sig, self.payload = data_bytes.split(b"#", maxsplit=1)
- self.signature = base64.decodebytes(sig)
- self.data = json.loads(self.payload)
-
- self.validate_data()
- self.details = self.get_details()
- self.digest = self.get_digest()
-
- self.ec_cert = self.get_cert_path("IL-NB-DSC-01.pem")
- self.rsa_cert = self.get_cert_path("RamzorQRPubKey.pem")
-
- def validate_data(self):
- ct = self.data["ct"]
- if ct not in (1, 2):
- raise Exception(f"Unknown certificate type {ct=}")
-
- def get_cert_path(self, name):
- return Path(__file__).absolute().parent / "certs" / name
-
- def get_details(self):
- details = []
- data = self.data
- if data["ct"] == 1:
- for i in range(len(data["p"])):
- details.append(
- {
- "id_num": data["p"][i]["idl"],
- "valid_by": data["p"][i]["e"],
- "cert_id": data["id"],
- }
- )
- elif data["ct"] == 2:
- details.append(
- {
- "id_num": data["idl"],
- "valid_by": data["e"],
- "cert_id": data["id"],
- }
- )
- return details
-
- def get_digest(self):
- ct = self.data["ct"]
- if ct == 1:
- digest = self.payload.decode().encode("utf8")
- elif ct == 2:
- h = hashes.Hash(hashes.SHA256())
- h.update(self.payload)
- digest = h.finalize()
- return digest
-
- def verify(self):
- for d in self.details:
- print(f"\tIsraeli ID Number {d['id_num']}")
- print(f"\tID valid by {d['valid_by']}")
- print(f"\tCert Unique ID {d['cert_id']}")
-
- certs = [
- [
- self.rsa_cert,
- [
- padding.PKCS1v15(),
- hashes.SHA256(),
- ],
- ],
- [self.ec_cert, [ec.ECDSA(hashes.SHA256())]],
- ]
- for cert, method in certs:
- with open(cert, "rb") as f:
- k = serialization.load_pem_public_key(f.read())
- try:
- k.verify(self.signature, self.digest, *method)
- return True
- except InvalidSignature:
- pass
- else:
- return False
diff --git a/greenpass/verifiers/base.py b/greenpass/verifiers/base.py
index c8ccdf6..61689f6 100644
--- a/greenpass/verifiers/base.py
+++ b/greenpass/verifiers/base.py
@@ -4,3 +4,6 @@ class Verifier(object):
def verify(self):
raise NotImplementedError()
+
+ def get_cert_path(self, name):
+ return Path(__file__).absolute().parent / "certs" / name
diff --git a/greenpass/verifiers/eu.py b/greenpass/verifiers/eu.py
index 2c89c2f..1337da5 100644
--- a/greenpass/verifiers/eu.py
+++ b/greenpass/verifiers/eu.py
@@ -1,6 +1,99 @@
+import base64
+import fitz
+import json
+
+from io import BytesIO
+from pathlib import Path
+
+from cryptography.hazmat.primitives import hashes, serialization
+from cryptography.hazmat.primitives.asymmetric import padding, ec
+from cryptography.exceptions import InvalidSignature
+from PIL import Image
+from pyzbar import pyzbar
+
from .base import Verifier
+class GreenPassVerifier(object):
+ def __init__(self, data_bytes):
+ self.validate_bytes(data_bytes)
+
+ sig, self.payload = data_bytes.split(b"#", maxsplit=1)
+ self.signature = base64.decodebytes(sig)
+ self.data = json.loads(self.payload)
+
+ self.validate_data()
+ self.details = self.get_details()
+ self.digest = self.get_digest()
+
+ self.ec_cert = self.get_cert_path("IL-NB-DSC-01.pem")
+ self.rsa_cert = self.get_cert_path("RamzorQRPubKey.pem")
+
+ def validate_data(self):
+ ct = self.data["ct"]
+ if ct not in (1, 2):
+ raise Exception(f"Unknown certificate type {ct=}")
+
+ def get_details(self):
+ details = []
+ data = self.data
+ if data["ct"] == 1:
+ for i in range(len(data["p"])):
+ details.append(
+ {
+ "id_num": data["p"][i]["idl"],
+ "valid_by": data["p"][i]["e"],
+ "cert_id": data["id"],
+ }
+ )
+ elif data["ct"] == 2:
+ details.append(
+ {
+ "id_num": data["idl"],
+ "valid_by": data["e"],
+ "cert_id": data["id"],
+ }
+ )
+ return details
+
+ def get_digest(self):
+ ct = self.data["ct"]
+ if ct == 1:
+ digest = self.payload.decode().encode("utf8")
+ elif ct == 2:
+ h = hashes.Hash(hashes.SHA256())
+ h.update(self.payload)
+ digest = h.finalize()
+ return digest
+
+ def verify(self):
+ for d in self.details:
+ print(f"\tIsraeli ID Number {d['id_num']}")
+ print(f"\tID valid by {d['valid_by']}")
+ print(f"\tCert Unique ID {d['cert_id']}")
+
+ certs = [
+ [
+ self.rsa_cert,
+ [
+ padding.PKCS1v15(),
+ hashes.SHA256(),
+ ],
+ ],
+ [self.ec_cert, [ec.ECDSA(hashes.SHA256())]],
+ ]
+ for cert, method in certs:
+ with open(cert, "rb") as f:
+ k = serialization.load_pem_public_key(f.read())
+ try:
+ k.verify(self.signature, self.digest, *method)
+ return True
+ except InvalidSignature:
+ pass
+ else:
+ return False
+
+
class EuroVerifier(Verifier):
def verify(self):
return False