just_found_out_about_linters (#17)
This changed a bunch of code but no Reviewed-on: #17 Co-authored-by: ahtlon <git@ahtlon.de> Co-committed-by: ahtlon <git@ahtlon.de>
This commit was merged in pull request #17.
This commit is contained in:
@@ -1,33 +1,39 @@
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
import threading
|
||||
import time
|
||||
import os
|
||||
import secrets
|
||||
import threading
|
||||
import time
|
||||
|
||||
from typing import Optional
|
||||
from sqlmodel import Session
|
||||
from desfire import (
|
||||
DESFire,
|
||||
DESFireKey,
|
||||
PCSCDevice,
|
||||
diversify_key,
|
||||
get_list,
|
||||
to_hex_string,
|
||||
)
|
||||
from desfire.enums import (
|
||||
DESFireCommunicationMode,
|
||||
DESFireFileType,
|
||||
DESFireKeySettings,
|
||||
DESFireKeyType,
|
||||
)
|
||||
from desfire.schemas import FilePermissions, FileSettings, KeySettings
|
||||
from dotenv import load_dotenv
|
||||
from fastapi import HTTPException, status
|
||||
|
||||
from smartcard.CardRequest import CardRequest
|
||||
from smartcard.CardType import AnyCardType
|
||||
from smartcard.Exceptions import CardRequestTimeoutException
|
||||
|
||||
from desfire import DESFire, DESFireKey, PCSCDevice, diversify_key, get_list, to_hex_string
|
||||
from desfire.enums import DESFireCommunicationMode, DESFireFileType, DESFireKeySettings, DESFireKeyType
|
||||
from desfire.schemas import FilePermissions, FileSettings, KeySettings
|
||||
import desfire.exceptions as desExceptions
|
||||
from app.services.door import checkAccess, openDoor
|
||||
|
||||
from app.services.door import openDoor, closeDoor, isDoorOpen, checkAccess
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
#ENV vars
|
||||
# ENV vars
|
||||
load_dotenv()
|
||||
MIFARE_APP_MASTER_KEY = os.getenv('MIFARE_APP_MASTER_KEY')
|
||||
MIFARE_ACL_READ_BASE_KEY = os.getenv('MIFARE_ACL_READ_BASE_KEY')
|
||||
MIFARE_ACL_WRITE_BASE_KEY = os.getenv('MIFARE_ACL_WRITE_BASE_KEY')
|
||||
MIFARE_APP_MASTER_KEY = os.getenv("MIFARE_APP_MASTER_KEY")
|
||||
MIFARE_ACL_READ_BASE_KEY = os.getenv("MIFARE_ACL_READ_BASE_KEY")
|
||||
MIFARE_ACL_WRITE_BASE_KEY = os.getenv("MIFARE_ACL_WRITE_BASE_KEY")
|
||||
|
||||
# Constants
|
||||
MIFARE_APP_ID = "DEAFFE" # 7 bytes
|
||||
@@ -36,10 +42,15 @@ MIFARE_ACL_WRITE_BASE_KEY_ID = 0x2
|
||||
MIFARE_SYS_ID = "FF0000" # 3 bytes, can essentially be anything
|
||||
MIFARE_ENCRYPTED_FILE_ID = 0x1
|
||||
|
||||
|
||||
def checkForKey():
|
||||
if MIFARE_APP_MASTER_KEY == None:
|
||||
logger.critical("NO MASTER KEY LOADED")
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="No key loaded! Check application.")
|
||||
if MIFARE_APP_MASTER_KEY is None:
|
||||
logger.critical("NO MASTER KEY LOADED")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="No key loaded! Check application.",
|
||||
)
|
||||
|
||||
|
||||
def getCardService(timeout: int = 10):
|
||||
cardtype = AnyCardType()
|
||||
@@ -48,51 +59,58 @@ def getCardService(timeout: int = 10):
|
||||
cardservice.connection.connect()
|
||||
return cardservice
|
||||
|
||||
|
||||
def readFileOnCard(desfire: DESFire):
|
||||
if not MIFARE_ACL_READ_BASE_KEY:
|
||||
logger.critical("MIFARE_ACL_READ_BASE_KEY not found! Reading skipped!")
|
||||
return
|
||||
#create keys
|
||||
#desfire = DESFire(PCSCDevice(cardservice.connection.component))
|
||||
# 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
|
||||
# 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)
|
||||
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
|
||||
# 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.debug("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.debug(f"Read data from {MIFARE_ENCRYPTED_FILE_ID}")
|
||||
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
|
||||
# convert list of int to str
|
||||
rdata = to_hex_string(rdata).replace(" ", "").lower()
|
||||
logger.debug(f"Data on card: {rdata}")
|
||||
return rdata
|
||||
|
||||
|
||||
def DeleteCard():
|
||||
try:
|
||||
checkForKey()
|
||||
from app.main import scanner as scannerThread
|
||||
|
||||
scannerThread.stop()
|
||||
cardservice = getCardService(15)
|
||||
|
||||
@@ -107,12 +125,12 @@ def DeleteCard():
|
||||
desKey = DESFireKey(des_keysettings, "00" * 8)
|
||||
aes_master_key = DESFireKey(aes_keysettings, MIFARE_APP_MASTER_KEY)
|
||||
aes_null_key = DESFireKey(aes_keysettings, "00" * 16)
|
||||
|
||||
|
||||
desfire.select_application(0x0)
|
||||
|
||||
try:
|
||||
try:
|
||||
logger.debug("Auth1")#
|
||||
logger.debug("Auth1")
|
||||
desfire.authenticate(0x0, aes_master_key)
|
||||
except:
|
||||
logger.debug("Auth2")
|
||||
@@ -120,11 +138,13 @@ def DeleteCard():
|
||||
except:
|
||||
logger.debug("Auth3")
|
||||
desfire.authenticate(0x0, desKey)
|
||||
|
||||
|
||||
applications = desfire.get_application_ids()
|
||||
logger.debug(f"Applications: {applications}")
|
||||
if len(applications) == 0:
|
||||
raise HTTPException(status_code=status.HTTP_410_GONE, detail="No applications on card")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_410_GONE, detail="No applications on card"
|
||||
)
|
||||
|
||||
desfire.select_application(MIFARE_APP_ID)
|
||||
desfire.authenticate(0x0, aes_master_key)
|
||||
@@ -136,14 +156,18 @@ def DeleteCard():
|
||||
pass
|
||||
scannerThread.start()
|
||||
return rdata
|
||||
except(Exception, AssertionError) as e:
|
||||
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}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Error: {e}"
|
||||
)
|
||||
|
||||
|
||||
def WriteNewCard():
|
||||
try:
|
||||
checkForKey()
|
||||
from app.main import scanner as scannerThread
|
||||
|
||||
scannerThread.stop()
|
||||
|
||||
cardservice = getCardService(20)
|
||||
@@ -159,8 +183,8 @@ def WriteNewCard():
|
||||
# Authenticate with default DES key
|
||||
logger.debug("Authenticating with default DES key...")
|
||||
desfire.authenticate(0x0, desKey)
|
||||
|
||||
#get uid
|
||||
|
||||
# get uid
|
||||
uid = desfire.get_real_uid()
|
||||
|
||||
# Set default key
|
||||
@@ -189,7 +213,7 @@ def WriteNewCard():
|
||||
# Select application
|
||||
desfire.select_application(MIFARE_APP_ID)
|
||||
|
||||
#recreate key object
|
||||
# recreate key object
|
||||
desfire.authenticate(0x0, aes_null_key)
|
||||
desfire.change_key(0x0, aes_null_key, aes_master_key, 0x1)
|
||||
|
||||
@@ -198,18 +222,28 @@ def WriteNewCard():
|
||||
|
||||
aes_null_key = DESFireKey(aes_keysettings, "00" * 16)
|
||||
|
||||
#generate div data
|
||||
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)
|
||||
write_div_key_bytes = diversify_key(get_list(MIFARE_ACL_WRITE_BASE_KEY), diversification_data, pad_to_32=False)
|
||||
|
||||
# generate div data
|
||||
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
|
||||
)
|
||||
write_div_key_bytes = diversify_key(
|
||||
get_list(MIFARE_ACL_WRITE_BASE_KEY), diversification_data, pad_to_32=False
|
||||
)
|
||||
|
||||
logger.debug("Changing file read key...")
|
||||
aes_file_read_key = DESFireKey(aes_keysettings, read_div_key_bytes)
|
||||
desfire.change_key(MIFARE_ACL_READ_BASE_KEY_ID, aes_null_key, aes_file_read_key, 0x1)
|
||||
desfire.change_key(
|
||||
MIFARE_ACL_READ_BASE_KEY_ID, aes_null_key, aes_file_read_key, 0x1
|
||||
)
|
||||
|
||||
logger.debug("Changing file write key...")
|
||||
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)
|
||||
desfire.change_key(
|
||||
MIFARE_ACL_WRITE_BASE_KEY_ID, aes_null_key, aes_file_write_key, 0x1
|
||||
)
|
||||
|
||||
logger.debug("Create encrypted file containing key...")
|
||||
file_settings = FileSettings(
|
||||
@@ -226,25 +260,29 @@ def WriteNewCard():
|
||||
|
||||
logger.debug("Writing UID to encrypted file...")
|
||||
key = secrets.token_hex(16)
|
||||
desfire.write_file_data(MIFARE_ENCRYPTED_FILE_ID, 0x0, file_data.encryption, get_list(key))
|
||||
desfire.write_file_data(
|
||||
MIFARE_ENCRYPTED_FILE_ID, 0x0, file_data.encryption, get_list(key)
|
||||
)
|
||||
|
||||
logger.debug("Reading from encrypted file...")
|
||||
rdata = desfire.read_file_data(MIFARE_ENCRYPTED_FILE_ID, file_data)
|
||||
assert rdata == get_list(key)
|
||||
logger.debug(" - Data written successfully.")
|
||||
scannerThread.start()
|
||||
return key, to_hex_string(data=uid, separator=":")
|
||||
return key, to_hex_string(data=uid, separator=":")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error in write function: {e}", exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Error: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Error: {e}"
|
||||
)
|
||||
|
||||
|
||||
class BackgroundScanner:
|
||||
def __init__(self, db):
|
||||
self.db = db
|
||||
self.is_running = False
|
||||
self.thread: Optional[threading.Thread] = None
|
||||
self.thread: threading.Thread | None = None
|
||||
|
||||
def start(self):
|
||||
if self.is_running:
|
||||
@@ -292,10 +330,10 @@ class BackgroundScanner:
|
||||
except Exception as e:
|
||||
logger.error(f"something went wrong: {e}")
|
||||
time.sleep(5)
|
||||
|
||||
|
||||
def _check_db(self, key):
|
||||
check = checkAccess(key, self.db)
|
||||
if check == True:
|
||||
if check:
|
||||
openDoor()
|
||||
logger.info("Access granted!")
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user