From ab6897c4cd7f5e0c019f69b2e10ce552bde12127 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 9 Jul 2023 16:21:23 +0200 Subject: [PATCH] pySim/transport: More type annotations Change-Id: I62e081271e3a579851a588a4ed7282017e56f852 --- pySim/transport/__init__.py | 23 +++++++++++++---------- pySim/transport/calypso.py | 10 ++++++---- pySim/transport/modem_atcmd.py | 6 ++++-- pySim/transport/pcsc.py | 10 ++++++---- pySim/transport/serial.py | 9 +++++---- pySim/utils.py | 3 ++- 6 files changed, 36 insertions(+), 25 deletions(-) diff --git a/pySim/transport/__init__.py b/pySim/transport/__init__.py index 09752ac6..a16fdb3e 100644 --- a/pySim/transport/__init__.py +++ b/pySim/transport/__init__.py @@ -6,10 +6,11 @@ import abc import argparse from typing import Optional, Tuple +from construct import Construct from pySim.exceptions import * from pySim.construct import filter_dict -from pySim.utils import sw_match, b2h, h2b, i2h, Hexstr +from pySim.utils import sw_match, b2h, h2b, i2h, Hexstr, SwHexstr, SwMatchstr from pySim.cat import ProactiveCommand, CommandDetails, DeviceIdentities, Result # @@ -60,14 +61,14 @@ class ProactiveHandler(abc.ABC): class LinkBase(abc.ABC): """Base class for link/transport to card.""" - def __init__(self, sw_interpreter=None, apdu_tracer=None, + def __init__(self, sw_interpreter=None, apdu_tracer: Optional[ApduTracer]=None, proactive_handler: Optional[ProactiveHandler]=None): self.sw_interpreter = sw_interpreter self.apdu_tracer = apdu_tracer self.proactive_handler = proactive_handler @abc.abstractmethod - def _send_apdu_raw(self, pdu: str) -> Tuple[str, str]: + def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, Hexstr]: """Implementation specific method for sending the PDU.""" def set_sw_interpreter(self, interp): @@ -75,7 +76,7 @@ class LinkBase(abc.ABC): self.sw_interpreter = interp @abc.abstractmethod - def wait_for_card(self, timeout: int = None, newcardonly: bool = False): + def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False): """Wait for a card and connect to it Args: @@ -98,7 +99,7 @@ class LinkBase(abc.ABC): """Resets the card (power down/up) """ - def send_apdu_raw(self, pdu: str): + def send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]: """Sends an APDU with minimal processing Args: @@ -115,7 +116,7 @@ class LinkBase(abc.ABC): self.apdu_tracer.trace_response(pdu, sw, data) return (data, sw) - def send_apdu(self, pdu): + def send_apdu(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]: """Sends an APDU and auto fetch response data Args: @@ -144,7 +145,7 @@ class LinkBase(abc.ABC): return data, sw - def send_apdu_checksw(self, pdu, sw="9000"): + def send_apdu_checksw(self, pdu: Hexstr, sw: SwMatchstr = "9000") -> Tuple[Hexstr, SwHexstr]: """Sends an APDU and check returned SW Args: @@ -212,7 +213,8 @@ class LinkBase(abc.ABC): raise SwMatchError(rv[1], sw.lower(), self.sw_interpreter) return rv - def send_apdu_constr(self, cla, ins, p1, p2, cmd_constr, cmd_data, resp_constr): + def send_apdu_constr(self, cla: Hexstr, ins: Hexstr, p1: Hexstr, p2: Hexstr, cmd_constr: Construct, + cmd_data: Hexstr, resp_constr: Construct) -> Tuple[dict, SwHexstr]: """Build and sends an APDU using a 'construct' definition; parses response. Args: @@ -237,8 +239,9 @@ class LinkBase(abc.ABC): rsp = None return (rsp, sw) - def send_apdu_constr_checksw(self, cla, ins, p1, p2, cmd_constr, cmd_data, resp_constr, - sw_exp="9000"): + def send_apdu_constr_checksw(self, cla: Hexstr, ins: Hexstr, p1: Hexstr, p2: Hexstr, + cmd_constr: Construct, cmd_data: Hexstr, resp_constr: Construct, + sw_exp: SwMatchstr="9000") -> Tuple[dict, SwHexstr]: """Build and sends an APDU using a 'construct' definition; parses response. Args: diff --git a/pySim/transport/calypso.py b/pySim/transport/calypso.py index e1326ac5..4244b230 100644 --- a/pySim/transport/calypso.py +++ b/pySim/transport/calypso.py @@ -21,9 +21,11 @@ import struct import socket import os +from typing import Optional, Tuple + from pySim.transport import LinkBase from pySim.exceptions import * -from pySim.utils import h2b, b2h +from pySim.utils import h2b, b2h, Hexstr, SwHexstr class L1CTLMessage: @@ -91,7 +93,7 @@ class CalypsoSimLink(LinkBase): def __del__(self): self.sock.close() - def wait_for_rsp(self, exp_len=128): + def wait_for_rsp(self, exp_len: int = 128): # Wait for incoming data (timeout is 3 seconds) s, _, _ = select.select([self.sock], [], [], 3.0) if not s: @@ -118,10 +120,10 @@ class CalypsoSimLink(LinkBase): def disconnect(self): pass # Nothing to do really ... - def wait_for_card(self, timeout=None, newcardonly=False): + def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False): pass # Nothing to do really ... - def _send_apdu_raw(self, pdu): + def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]: # Request FULL reset req_msg = L1CTLMessageSIM(h2b(pdu)) diff --git a/pySim/transport/modem_atcmd.py b/pySim/transport/modem_atcmd.py index ea50bc9d..c6f6c57e 100644 --- a/pySim/transport/modem_atcmd.py +++ b/pySim/transport/modem_atcmd.py @@ -20,7 +20,9 @@ import logging as log import serial import time import re +from typing import Optional, Tuple +from pySim.utils import Hexstr, SwHexstr from pySim.transport import LinkBase from pySim.exceptions import * @@ -136,10 +138,10 @@ class ModemATCommandLink(LinkBase): def disconnect(self): pass # Nothing to do really ... - def wait_for_card(self, timeout=None, newcardonly=False): + def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False): pass # Nothing to do really ... - def _send_apdu_raw(self, pdu): + def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]: # Make sure pdu has upper case hex digits [A-F] pdu = pdu.upper() diff --git a/pySim/transport/pcsc.py b/pySim/transport/pcsc.py index e3f2546f..f0b3e67a 100644 --- a/pySim/transport/pcsc.py +++ b/pySim/transport/pcsc.py @@ -17,6 +17,8 @@ # along with this program. If not, see . # +from typing import Optional, Tuple + from smartcard.CardConnection import CardConnection from smartcard.CardRequest import CardRequest from smartcard.Exceptions import NoCardException, CardRequestTimeoutException, CardConnectionException, CardConnectionException @@ -24,7 +26,7 @@ from smartcard.System import readers from pySim.exceptions import NoCardError, ProtocolError, ReaderError from pySim.transport import LinkBase -from pySim.utils import h2i, i2h +from pySim.utils import h2i, i2h, Hexstr, SwHexstr class PcscSimLink(LinkBase): @@ -46,7 +48,7 @@ class PcscSimLink(LinkBase): pass return - def wait_for_card(self, timeout: int = None, newcardonly: bool = False): + def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False): cr = CardRequest(readers=[self._reader], timeout=timeout, newcardonly=newcardonly) try: @@ -68,7 +70,7 @@ class PcscSimLink(LinkBase): except NoCardException: raise NoCardError() - def get_atr(self): + def get_atr(self) -> Hexstr: return self._con.getATR() def disconnect(self): @@ -79,7 +81,7 @@ class PcscSimLink(LinkBase): self.connect() return 1 - def _send_apdu_raw(self, pdu): + def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]: apdu = h2i(pdu) diff --git a/pySim/transport/serial.py b/pySim/transport/serial.py index 3313a5e1..daf2eb82 100644 --- a/pySim/transport/serial.py +++ b/pySim/transport/serial.py @@ -19,10 +19,11 @@ import serial import time import os.path +from typing import Optional, Tuple from pySim.exceptions import NoCardError, ProtocolError from pySim.transport import LinkBase -from pySim.utils import h2b, b2h +from pySim.utils import h2b, b2h, Hexstr, SwHexstr class SerialSimLink(LinkBase): @@ -51,7 +52,7 @@ class SerialSimLink(LinkBase): if (hasattr(self, "_sl")): self._sl.close() - def wait_for_card(self, timeout=None, newcardonly=False): + def wait_for_card(self, timeout: Optional[int] = None, newcardonly: bool = False): # Direct try existing = False @@ -92,7 +93,7 @@ class SerialSimLink(LinkBase): def connect(self): self.reset_card() - def get_atr(self): + def get_atr(self) -> Hexstr: return self._atr def disconnect(self): @@ -184,7 +185,7 @@ class SerialSimLink(LinkBase): def _rx_byte(self): return self._sl.read() - def _send_apdu_raw(self, pdu): + def _send_apdu_raw(self, pdu: Hexstr) -> Tuple[Hexstr, SwHexstr]: pdu = h2b(pdu) data_len = pdu[4] # P3 diff --git a/pySim/utils.py b/pySim/utils.py index b5345802..22dcda33 100644 --- a/pySim/utils.py +++ b/pySim/utils.py @@ -28,7 +28,8 @@ from typing import Optional, List, Dict, Any, Tuple, NewType # just to differentiate strings of hex nibbles from everything else Hexstr = NewType('Hexstr', str) - +SwHexstr = NewType('SwHexstr', str) +SwMatchstr = NewType('SwMatchstr', str) def h2b(s: Hexstr) -> bytearray: """convert from a string of hex nibbles to a sequence of bytes"""