53 lines
1.6 KiB
Python
53 lines
1.6 KiB
Python
import hashlib
|
|
from cryptography.hazmat.primitives import hashes
|
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
from cryptography.hazmat.primitives.asymmetric import padding
|
|
|
|
|
|
class Card:
|
|
"""
|
|
Represent the card of an elector.
|
|
"""
|
|
|
|
def __init__(self, name: str, pin: int):
|
|
self.name = name
|
|
|
|
self.private_key = rsa.generate_private_key(
|
|
public_exponent=65537,
|
|
key_size=2048,
|
|
)
|
|
self._public_key = self.private_key.public_key()
|
|
|
|
digest = hashes.Hash(hashes.SHA256())
|
|
digest.update(pin.to_bytes())
|
|
self.hashed_pin = digest.finalize()
|
|
# self.activee = False
|
|
|
|
@property
|
|
def public_key(self):
|
|
return self._public_key
|
|
|
|
def check_pin(self, hashed_pin: bytes) -> bool:
|
|
"""
|
|
Check if the card is valid by comparing hashed PIN.
|
|
:param pin_hash: The PIN to check.
|
|
:return: True if the received hash PIN matches the stored hashed PIN, False otherwise.
|
|
"""
|
|
return self.hashed_pin == hashed_pin
|
|
|
|
# NOTE(Faraphel): a PKI or a banlist / whitelist shall be checked with self.public_key
|
|
|
|
def reply_challenge(self, data: bytes = "encrypted data") -> bytes:
|
|
"""
|
|
:param data: The challeng sent by the terminal to sign.
|
|
:return: The signed challenge.
|
|
"""
|
|
signature = self.private_key.sign(
|
|
data,
|
|
padding.PSS(
|
|
mgf=padding.MGF1(hashes.SHA256()),
|
|
salt_length=padding.PSS.MAX_LENGTH
|
|
),
|
|
hashes.SHA256()
|
|
)
|
|
return signature
|