Scanner write-read-delete workflow working!
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlmodel import Session, select
|
||||
from typing import List
|
||||
from sqlalchemy.exc import NoResultFound
|
||||
|
||||
from ..model.models import Card
|
||||
from ..services.database import engine, get_session, add_and_refresh
|
||||
@@ -26,13 +27,16 @@ def add_card(*, db: Session = Depends(get_session), group_id: int, admin: bool =
|
||||
@card_router.get("/delete")
|
||||
def del_card(*, db: Session = Depends(get_session), admin: bool = Depends(auth_is_admin)):
|
||||
key = DeleteCard()
|
||||
# card = db.get(Card, card_id)
|
||||
# if card is None:
|
||||
# raise HTTPException(status_code=404, detail="Card not found")
|
||||
# db.delete(card)
|
||||
# db.commit()
|
||||
# return {"message": "Card deleted successfully"}
|
||||
##TBH not a big fan of having creation using group_id but deletion using card_id
|
||||
print(key)
|
||||
try:
|
||||
card = db.exec(select(Card).where(Card.uuid == key)).one()
|
||||
except NoResultFound:
|
||||
print(f"The key:'{key}' was not found in db!")
|
||||
raise HTTPException(status_code=500, detail="Key on card not found in DB. Please tell an admin about this. KEY={key}")
|
||||
db.delete(card)
|
||||
db.commit()
|
||||
return {"message": "Card deleted successfully"}
|
||||
|
||||
@card_router.get("/{group_id}", response_model=List[Card])
|
||||
def get_cards(*, db: Session = Depends(get_session), group_id: int, admin: bool = Depends(auth_is_admin)):
|
||||
cards = db.exec(select(Card).where(Card.group_id == group_id)).all()
|
||||
|
||||
@@ -44,34 +44,80 @@ def checkForKey():
|
||||
def getCardService(timeout: int = 10):
|
||||
cardtype = AnyCardType()
|
||||
cardrequest = CardRequest(timeout=timeout, cardType=cardtype)
|
||||
print("Please present DESfire tag...")
|
||||
try:
|
||||
cardservice = cardrequest.waitforcard()
|
||||
except CardRequestTimeoutException:
|
||||
logger.error("No tag detected within the timeout.")
|
||||
raise Exception("No tag detected within the timeout.")
|
||||
cardservice = cardrequest.waitforcard()
|
||||
cardservice.connection.connect()
|
||||
return cardservice
|
||||
|
||||
def readFileOnCard(desfire: DESFire):
|
||||
#create keys
|
||||
#desfire = DESFire(PCSCDevice(cardservice.connection.component))
|
||||
aes_keysettings = KeySettings(key_type=DESFireKeyType.DF_KEY_AES)
|
||||
keysettings = desfire.get_key_setting()
|
||||
desKey = DESFireKey(keysettings, "00" * 8)
|
||||
|
||||
# Get real UID
|
||||
desfire.authenticate(0x0, desKey)
|
||||
#To get the uid you have to auth with an empty (default) key
|
||||
uid = desfire.get_real_uid()
|
||||
applications = desfire.get_application_ids()
|
||||
try:
|
||||
assert len(applications) == 1
|
||||
assert applications[0] == get_list(MIFARE_APP_ID)
|
||||
except AssertionError:
|
||||
logger.error("No application found!")
|
||||
time.sleep(4)
|
||||
return
|
||||
#Then use the key derivation with that uid, the appid, the sysid
|
||||
diversification_data = [0x01] + uid + get_list(MIFARE_APP_ID) + get_list(MIFARE_SYS_ID)
|
||||
read_div_key_bytes = diversify_key(get_list(MIFARE_ACL_READ_BASE_KEY), diversification_data, pad_to_32=False)
|
||||
|
||||
#Log in with derived read key
|
||||
logger.info("Start auth")
|
||||
aes_app_read_key = DESFireKey(aes_keysettings, read_div_key_bytes)
|
||||
desfire.select_application(MIFARE_APP_ID)
|
||||
|
||||
desfire.authenticate(MIFARE_ACL_READ_BASE_KEY_ID, aes_app_read_key)
|
||||
|
||||
logger.info("Read data")
|
||||
file_data = desfire.get_file_settings(MIFARE_ENCRYPTED_FILE_ID)
|
||||
rdata = desfire.read_file_data(MIFARE_ENCRYPTED_FILE_ID, file_data)
|
||||
#convert list of int to str
|
||||
rdata = to_hex_string(rdata).replace(" ", "").lower()
|
||||
logger.info(f"Data on card: {rdata}")
|
||||
return rdata
|
||||
|
||||
def DeleteCard():
|
||||
try:
|
||||
checkForKey()
|
||||
from app.main import scanner as scannerThread
|
||||
scannerThread.stop()
|
||||
cardservice = getCardService(15)
|
||||
cardservice.connection.connect()
|
||||
|
||||
# Create Desfire object
|
||||
desfire = DESFire(PCSCDevice(cardservice.connection.component))
|
||||
|
||||
rdata = readFileOnCard(desfire=desfire)
|
||||
|
||||
# Create Key objects
|
||||
AES_NULL_KEY_DATA = "00" * 8
|
||||
aes_keysettings = KeySettings(
|
||||
key_type=DESFireKeyType.DF_KEY_AES,
|
||||
)
|
||||
key_settings = desfire.get_key_setting()
|
||||
aes_null_key = DESFireKey(key_settings, AES_NULL_KEY_DATA)
|
||||
aes_keysettings = KeySettings(key_type=DESFireKeyType.DF_KEY_AES)
|
||||
des_keysettings = KeySettings(key_type=DESFireKeyType.DF_KEY_2K3DES)
|
||||
desKey = DESFireKey(des_keysettings, "00" * 8)
|
||||
aes_master_key = DESFireKey(aes_keysettings, MIFARE_APP_MASTER_KEY)
|
||||
desfire.authenticate(0x0, aes_null_key)
|
||||
aes_null_key = DESFireKey(aes_keysettings, "00" * 16)
|
||||
|
||||
desfire.select_application(0x0)
|
||||
|
||||
try:
|
||||
try:
|
||||
logger.info("Auth1")
|
||||
desfire.authenticate(0x0, desKey)
|
||||
except:
|
||||
logger.info("Auth2")
|
||||
desfire.authenticate(0x0, aes_null_key)
|
||||
except:
|
||||
logger.info("Auth3")
|
||||
desfire.authenticate(0x0, aes_master_key)
|
||||
|
||||
applications = desfire.get_application_ids()
|
||||
logger.debug(f"Applications: {applications}")
|
||||
if len(applications) == 0:
|
||||
@@ -79,13 +125,15 @@ def DeleteCard():
|
||||
|
||||
desfire.select_application(MIFARE_APP_ID)
|
||||
desfire.authenticate(0x0, aes_master_key)
|
||||
|
||||
try:
|
||||
desfire.delete_application(MIFARE_APP_ID)
|
||||
logger.info("App deleted!")
|
||||
except Exception:
|
||||
pass
|
||||
scannerThread.start()
|
||||
|
||||
except Exception as e:
|
||||
return rdata
|
||||
except(Exception, AssertionError) as e:
|
||||
logger.error(f"Error in deletion function: {e}", exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Error: {e}")
|
||||
|
||||
@@ -96,7 +144,6 @@ def WriteNewCard():
|
||||
scannerThread.stop()
|
||||
|
||||
cardservice = getCardService(20)
|
||||
cardservice.connection.connect()
|
||||
|
||||
desfire = DESFire(PCSCDevice(cardservice.connection.component))
|
||||
|
||||
@@ -104,8 +151,7 @@ def WriteNewCard():
|
||||
aes_keysettings = KeySettings(key_type=DESFireKeyType.DF_KEY_AES)
|
||||
aes_null_key = DESFireKey(aes_keysettings, "00" * 16)
|
||||
aes_master_key = DESFireKey(aes_keysettings, MIFARE_APP_MASTER_KEY)
|
||||
keysetting = desfire.get_key_setting()
|
||||
desKey = DESFireKey(keysetting, "00" * 8)
|
||||
desKey = DESFireKey(desfire.get_key_setting(), "00" * 8)
|
||||
|
||||
# Authenticate with default DES key
|
||||
print("Authenticating with default DES key...")
|
||||
@@ -162,7 +208,7 @@ def WriteNewCard():
|
||||
aes_file_write_key = DESFireKey(aes_keysettings, write_div_key_bytes)
|
||||
desfire.change_key(MIFARE_ACL_WRITE_BASE_KEY_ID, aes_null_key, aes_file_write_key, 0x1)
|
||||
|
||||
print("Create encrypted file containing UUID...")
|
||||
print("Create encrypted file containing key...")
|
||||
file_settings = FileSettings(
|
||||
file_size=16,
|
||||
encryption=DESFireCommunicationMode.ENCRYPTED,
|
||||
@@ -173,16 +219,7 @@ def WriteNewCard():
|
||||
file_type=DESFireFileType.MDFT_STANDARD_DATA_FILE,
|
||||
)
|
||||
desfire.create_standard_file(MIFARE_ENCRYPTED_FILE_ID, file_settings)
|
||||
|
||||
print("Read and verify file settings again...")
|
||||
file_data = desfire.get_file_settings(MIFARE_ENCRYPTED_FILE_ID)
|
||||
assert file_data.file_size == 16
|
||||
assert file_data.encryption == DESFireCommunicationMode.ENCRYPTED
|
||||
assert file_data.permissions is not None
|
||||
assert file_data.permissions.read_access == MIFARE_ACL_READ_BASE_KEY_ID
|
||||
assert file_data.permissions.write_access == MIFARE_ACL_WRITE_BASE_KEY_ID
|
||||
assert file_data.file_type == DESFireFileType.MDFT_STANDARD_DATA_FILE
|
||||
print(" - File created successfully.")
|
||||
|
||||
print("Writing UID to encrypted file...")
|
||||
key = secrets.token_hex(16)
|
||||
@@ -226,7 +263,7 @@ class BackgroundScanner:
|
||||
try:
|
||||
card_content = self._read_card()
|
||||
if card_content:
|
||||
logger.info(to_hex_string(card_content))
|
||||
logger.info(f"content: {card_content}")
|
||||
time.sleep(5)
|
||||
logger.debug("READY after success")
|
||||
#self._check_db(card_content)
|
||||
@@ -239,53 +276,17 @@ class BackgroundScanner:
|
||||
time.sleep(6)
|
||||
|
||||
def _read_card(self):
|
||||
cardtype = AnyCardType()
|
||||
cardrequest = CardRequest(timeout=5, cardType=cardtype)
|
||||
time.sleep(0.5)
|
||||
try:
|
||||
cardservice = cardrequest.waitforcard()
|
||||
cardservice = getCardService(3)
|
||||
except CardRequestTimeoutException:
|
||||
logger.debug("No tag detected within the timeout.")
|
||||
return
|
||||
|
||||
# Create Desfire object
|
||||
desfire = DESFire(PCSCDevice(cardservice.connection.component))
|
||||
try:
|
||||
cardservice.connection.connect()
|
||||
|
||||
# Create Desfire object
|
||||
desfire = DESFire(PCSCDevice(cardservice.connection.component))
|
||||
aes_keysettings = KeySettings(
|
||||
key_type=DESFireKeyType.DF_KEY_AES,
|
||||
)
|
||||
|
||||
# Get real UID
|
||||
mk = DESFireKey(desfire.get_key_setting(), "00" * 8)
|
||||
desfire.authenticate(0x0, mk)
|
||||
#To get the uid you have to auth with an empty (default) key
|
||||
uid = desfire.get_real_uid()
|
||||
applications = desfire.get_application_ids()
|
||||
try:
|
||||
assert len(applications) == 1
|
||||
assert applications[0] == get_list(MIFARE_APP_ID)
|
||||
except AssertionError:
|
||||
logger.error("No application found!")
|
||||
time.sleep(4)
|
||||
return None
|
||||
#Then use the key derivation with that uid, the appid, the sysid
|
||||
diversification_data = [0x01] + uid + get_list(MIFARE_APP_ID) + get_list(MIFARE_SYS_ID)
|
||||
read_div_key_bytes = diversify_key(get_list(MIFARE_ACL_READ_BASE_KEY), diversification_data, pad_to_32=False)
|
||||
|
||||
#Log in with derived read key
|
||||
logger.info("Start auth")
|
||||
aes_app_read_key = DESFireKey(aes_keysettings, read_div_key_bytes)
|
||||
desfire.select_application(MIFARE_APP_ID)
|
||||
|
||||
desfire.authenticate(MIFARE_ACL_READ_BASE_KEY_ID, aes_app_read_key)
|
||||
|
||||
logger.info("Read data")
|
||||
file_data = desfire.get_file_settings(MIFARE_ENCRYPTED_FILE_ID)
|
||||
logger.info(f"File settings: {file_data}")
|
||||
rdata = desfire.read_file_data(MIFARE_ENCRYPTED_FILE_ID, file_data)
|
||||
rdata = readFileOnCard(desfire=desfire)
|
||||
return rdata
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"something went wrong: {e}")
|
||||
time.sleep(5)
|
||||
Reference in New Issue
Block a user