pySim library

pySim filesystem abstraction

Representation of the ISO7816-4 filesystem model.

The File (and its derived classes) represent the structure / hierarchy of the ISO7816-4 smart card file system with the MF, DF, EF and ADF entries, further sub-divided into the EF sub-types Transparent, Linear Fixed, etc.

The classes are intended to represent the specification of the filesystem, not the actual contents / runtime state of interacting with a given smart card.

class pySim.filesystem.BerTlvEF(fid: str, sfid: str = None, name: str = None, desc: str = None, parent: CardDF = None, size: Tuple[int, int | None] = (1, None), **kwargs)

BER-TLV EF (Entry File) in the smart card filesystem. A BER-TLV EF is a binary file with a BER (Basic Encoding Rules) TLV structure

NOTE: We currently don’t really support those, this class is simply a wrapper around TransparentEF as a place-holder, so we can already define EFs of BER-TLV type without fully supporting them.

Parameters:
  • fid – File Identifier (4 hex digits)

  • sfid – Short File Identifier (2 hex digits, optional)

  • name – Brief name of the file, lik EF_ICCID

  • desc – Description of the file

  • parent – Parent CardFile object within filesystem hierarchy

  • size – tuple of (minimum_size, recommended_size)

class ShellCommands

Shell commands specific for BER-TLV EFs.

do_delete_data(opts)

Delete data for a given tag in a BER-TLV EF

do_retrieve_data(opts)

Retrieve (Read) data from a BER-TLV EF

do_retrieve_tags(_opts)

List tags available in a given BER-TLV EF

do_set_data(opts)

Set (Write) data for a given tag in a BER-TLV EF

class pySim.filesystem.CardADF(aid: str, has_fs: bool = False, **kwargs)

ADF (Application Dedicated File) in the smart card filesystem

Parameters:
  • fid – File Identifier (4 hex digits)

  • sfid – Short File Identifier (2 hex digits, optional)

  • name – Brief name of the file, lik EF_ICCID

  • desc – Description of the file

  • parent – Parent CardFile object within filesystem hierarchy

  • profile – Card profile that this file should be part of

  • service – Service (SST/UST/IST) associated with the file

class pySim.filesystem.CardApplication(name, adf: CardADF | None = None, aid: str = None, sw: dict = None)

A card application is represented by an ADF (with contained hierarchy) and optionally some SW definitions.

Parameters:
  • adf – ADF name

  • sw – Dict of status word conversions

interpret_sw(sw)

Interpret a given status word within the application.

Parameters:

sw – Status word as string of 4 hex digits

Returns:

Tuple of two strings

class pySim.filesystem.CardDF(**kwargs)

DF (Dedicated File) in the smart card filesystem. Those are basically sub-directories.

Parameters:
  • fid – File Identifier (4 hex digits)

  • sfid – Short File Identifier (2 hex digits, optional)

  • name – Brief name of the file, lik EF_ICCID

  • desc – Description of the file

  • parent – Parent CardFile object within filesystem hierarchy

  • profile – Card profile that this file should be part of

  • service – Service (SST/UST/IST) associated with the file

class ShellCommands
add_file(child: CardFile, ignore_existing: bool = False)

Add a child (DF/EF) to this DF. :param child: The new DF/EF to be added :param ignore_existing: Ignore, if file with given FID already exists. Old one will be kept.

add_files(children: Iterable[CardFile], ignore_existing: bool = False)

Add a list of child (DF/EF) to this DF

Parameters:
  • children – List of new DF/EFs to be added

  • ignore_existing – Ignore, if file[s] with given FID already exists. Old one[s] will be kept.

get_selectables(flags=[]) dict

Return a dict of {‘identifier’: File} that is selectable from the current DF.

Parameters:

flags – Specify which selectables to return ‘FIDS’ and/or ‘NAMES’; If not specified, all selectables will be returned.

Returns:

dict containing all selectable items. Key is identifier (string), value a reference to a CardFile (or derived class) instance.

lookup_file_by_fid(fid: str) CardFile | None

Find a file with given file ID within current DF.

lookup_file_by_name(name: str | None) CardFile | None

Find a file with given name within current DF.

lookup_file_by_sfid(sfid: str | None) CardFile | None

Find a file with given short file ID within current DF.

class pySim.filesystem.CardEF(*, fid, **kwargs)

EF (Entry File) in the smart card filesystem

Parameters:
  • fid – File Identifier (4 hex digits)

  • sfid – Short File Identifier (2 hex digits, optional)

  • name – Brief name of the file, lik EF_ICCID

  • desc – Description of the file

  • parent – Parent CardFile object within filesystem hierarchy

  • profile – Card profile that this file should be part of

  • service – Service (SST/UST/IST) associated with the file

get_selectables(flags=[]) dict

Return a dict of {‘identifier’: File} that is selectable from the current DF.

Parameters:

flags – Specify which selectables to return ‘FIDS’ and/or ‘NAMES’; If not specified, all selectables will be returned.

Returns:

dict containing all selectable items. Key is identifier (string), value a reference to a CardFile (or derived class) instance.

class pySim.filesystem.CardFile(fid: str = None, sfid: str = None, name: str = None, desc: str = None, parent: CardDF | None = None, profile: CardProfile | None = None, service: int | List[int] | Tuple[int, ...] | None = None)

Base class for all objects in the smart card filesystem. Serve as a common ancestor to all other file types; rarely used directly.

Parameters:
  • fid – File Identifier (4 hex digits)

  • sfid – Short File Identifier (2 hex digits, optional)

  • name – Brief name of the file, lik EF_ICCID

  • desc – Description of the file

  • parent – Parent CardFile object within filesystem hierarchy

  • profile – Card profile that this file should be part of

  • service – Service (SST/UST/IST) associated with the file

build_select_path_to(target: CardFile) List[CardFile] | None

Build the relative sequence of files we need to traverse to get from us to ‘target’.

decode_select_response(data_hex: str)

Decode the response to a SELECT command.

Parameters:

data_hex – Hex string of the select response

fully_qualified_path(prefer_name: bool = True) List[str]

Return fully qualified path to file as list of FID or name strings.

Parameters:

prefer_name – Preferably build path of names; fall-back to FIDs as required

fully_qualified_path_fobj() List[CardFile]

Return fully qualified path to file as list of CardFile instance references.

fully_qualified_path_str(prefer_name: bool = True) str

Return fully qualified path to file as string.

Parameters:

prefer_name – Preferably build path of names; fall-back to FIDs as required

get_mf() CardMF | None

Return the MF (root) of the file system.

get_profile()

Get the profile associated with this file. If this file does not have any profile assigned, try to find a file above (usually the MF) in the filesystem hirarchy that has a profile assigned

get_selectable_names(flags=[]) List[str]

Return a dict of {‘identifier’: File} that is selectable from the current file.

Parameters:

flags – Specify which selectables to return ‘FIDS’ and/or ‘NAMES’; If not specified, all selectables will be returned.

Returns:

list containing all selectable names.

get_selectables(flags=[]) Dict[str, CardFile]

Return a dict of {‘identifier’: File} that is selectable from the current file.

Parameters:

flags – Specify which selectables to return ‘FIDS’ and/or ‘NAMES’; If not specified, all selectables will be returned.

Returns:

dict containing all selectable items. Key is identifier (string), value a reference to a CardFile (or derived class) instance.

should_exist_for_services(services: List[int])

Assuming the provided list of activated services, should this file exist and be activated?.

class pySim.filesystem.CardMF(**kwargs)

MF (Master File) in the smart card filesystem

Parameters:
  • fid – File Identifier (4 hex digits)

  • sfid – Short File Identifier (2 hex digits, optional)

  • name – Brief name of the file, lik EF_ICCID

  • desc – Description of the file

  • parent – Parent CardFile object within filesystem hierarchy

  • profile – Card profile that this file should be part of

  • service – Service (SST/UST/IST) associated with the file

add_application_df(app: CardADF)

Add an Application to the MF

decode_select_response(data_hex: str | None) object

Decode the response to a SELECT command.

This is the fall-back method which automatically defers to the standard decoding method defined by the card profile. When no profile is set, then no decoding is performed. Specific derived classes (usually ADF) can overload this method to install specific decoding.

get_app_names()

Get list of completions (AID names)

get_app_selectables(flags=[]) dict

Get applications by AID + name

get_selectables(flags=[]) dict

Return a dict of {‘identifier’: File} that is selectable from the current DF.

Parameters:

flags – Specify which selectables to return ‘FIDS’ and/or ‘NAMES’; If not specified, all selectables will be returned.

Returns:

dict containing all selectable items. Key is identifier (string), value a reference to a CardFile (or derived class) instance.

class pySim.filesystem.CardModel

A specific card model, typically having some additional vendor-specific files. All you need to do is to define a sub-class with a list of ATRs or an overridden match method.

abstract classmethod add_files(rs: RuntimeState)

Add model specific files to given RuntimeState.

static apply_matching_models(scc: SimCardCommands, rs: RuntimeState)

Check if any of the CardModel sub-classes ‘match’ the currently inserted card (by ATR or overriding the ‘match’ method). If so, call their ‘add_files’ method.

classmethod match(scc: SimCardCommands) bool

Test if given card matches this model.

class pySim.filesystem.CyclicEF(fid: str, sfid: str = None, name: str = None, desc: str = None, parent: CardDF = None, rec_len: Tuple[int, int | None] = (1, None), **kwargs)

Cyclic EF (Entry File) in the smart card filesystem

Parameters:
  • fid – File Identifier (4 hex digits)

  • sfid – Short File Identifier (2 hex digits, optional)

  • name – Brief name of the file, lik EF_ICCID

  • desc – Description of the file

  • parent – Parent CardFile object within filesystem hierarchy

  • rec_len – Tuple of (minimum_length, recommended_length)

  • leftpad – On write, data must be padded from the left to fit pysical record length

class pySim.filesystem.LinFixedEF(fid: str, sfid: str = None, name: str = None, desc: str = None, parent: CardDF | None = None, rec_len: Tuple[int, int | None] = (1, None), leftpad: bool = False, **kwargs)

Linear Fixed EF (Entry File) in the smart card filesystem.

Linear Fixed EFs are record oriented files. They consist of a number of fixed-size records. The records can be individually read/updated.

Parameters:
  • fid – File Identifier (4 hex digits)

  • sfid – Short File Identifier (2 hex digits, optional)

  • name – Brief name of the file, lik EF_ICCID

  • desc – Description of the file

  • parent – Parent CardFile object within filesystem hierarchy

  • rec_len – Tuple of (minimum_length, recommended_length)

  • leftpad – On write, data must be padded from the left to fit pysical record length

class ShellCommands

Shell commands specific for Linear Fixed EFs.

do_decode_hex(opts)

Decode command-line provided hex-string as if it was read from the file.

do_edit_record_decoded(opts)

Edit the JSON representation of one record in an editor.

do_read_record(opts)

Read one or multiple records from a record-oriented EF

do_read_record_decoded(opts)

Read + decode a record from a record-oriented EF

do_read_records(_opts)

Read all records from a record-oriented EF

do_read_records_decoded(opts)

Read + decode all records from a record-oriented EF

do_update_record(opts)

Update (write) data to a record-oriented EF

do_update_record_decoded(opts)

Encode + Update (write) data to a record-oriented EF

decode_record_bin(raw_bin_data: bytearray, record_nr: int) dict

Decode raw (binary) data into abstract representation.

A derived class would typically provide a _decode_record_bin() or _decode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:
  • raw_bin_data – binary encoded data

  • record_nr – record number (1 for first record, …)

Returns:

abstract_data; dict representing the decoded data

decode_record_hex(raw_hex_data: str, record_nr: int = 1) dict

Decode raw (hex string) data into abstract representation.

A derived class would typically provide a _decode_record_bin() or _decode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:
  • raw_hex_data – hex-encoded data

  • record_nr – record number (1 for first record, …)

Returns:

abstract_data; dict representing the decoded data

encode_record_bin(abstract_data: dict, record_nr: int) bytearray

Encode abstract representation into raw (binary) data.

A derived class would typically provide an _encode_record_bin() or _encode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:
  • abstract_data – dict representing the decoded data

  • record_nr – record number (1 for first record, …)

Returns:

binary encoded data

encode_record_hex(abstract_data: dict, record_nr: int) str

Encode abstract representation into raw (hex string) data.

A derived class would typically provide an _encode_record_bin() or _encode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:
  • abstract_data – dict representing the decoded data

  • record_nr – record number (1 for first record, …)

Returns:

hex string encoded data

class pySim.filesystem.TransRecEF(fid: str, rec_len: int, sfid: str = None, name: str = None, desc: str = None, parent: CardDF | None = None, size: Tuple[int, int | None] = (1, None), **kwargs)

Transparent EF (Entry File) containing fixed-size records.

These are the real odd-balls and mostly look like mistakes in the specification: Specified as ‘transparent’ EF, but actually containing several fixed-length records inside. We add a special class for those, so the user only has to provide encoder/decoder functions for a record, while this class takes care of split / merge of records.

Parameters:
  • fid – File Identifier (4 hex digits)

  • sfid – Short File Identifier (2 hex digits, optional)

  • name – Brief name of the file, like EF_ICCID

  • desc – Description of the file

  • parent – Parent CardFile object within filesystem hierarchy

  • rec_len – Length of the fixed-length records within transparent EF

  • size – tuple of (minimum_size, recommended_size)

decode_record_bin(raw_bin_data: bytearray) dict

Decode raw (binary) data into abstract representation.

A derived class would typically provide a _decode_record_bin() or _decode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:

raw_bin_data – binary encoded data

Returns:

abstract_data; dict representing the decoded data

decode_record_hex(raw_hex_data: str) dict

Decode raw (hex string) data into abstract representation.

A derived class would typically provide a _decode_record_bin() or _decode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:

raw_hex_data – hex-encoded data

Returns:

abstract_data; dict representing the decoded data

encode_record_bin(abstract_data: dict) bytearray

Encode abstract representation into raw (binary) data.

A derived class would typically provide an _encode_record_bin() or _encode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:

abstract_data – dict representing the decoded data

Returns:

binary encoded data

encode_record_hex(abstract_data: dict) str

Encode abstract representation into raw (hex string) data.

A derived class would typically provide an _encode_record_bin() or _encode_record_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:

abstract_data – dict representing the decoded data

Returns:

hex string encoded data

class pySim.filesystem.TransparentEF(fid: str, sfid: str = None, name: str = None, desc: str = None, parent: CardDF = None, size: Tuple[int, int | None] = (1, None), **kwargs)

Transparent EF (Entry File) in the smart card filesystem.

A Transparent EF is a binary file with no formal structure. This is contrary to Record based EFs which have [fixed size] records that can be individually read/updated.

Parameters:
  • fid – File Identifier (4 hex digits)

  • sfid – Short File Identifier (2 hex digits, optional)

  • name – Brief name of the file, lik EF_ICCID

  • desc – Description of the file

  • parent – Parent CardFile object within filesystem hierarchy

  • size – tuple of (minimum_size, recommended_size)

class ShellCommands

Shell commands specific for transparent EFs.

do_decode_hex(opts)

Decode command-line provided hex-string as if it was read from the file.

do_edit_binary_decoded(_opts)

Edit the JSON representation of the EF contents in an editor.

do_read_binary(opts)

Read binary data from a transparent EF

do_read_binary_decoded(opts)

Read + decode data from a transparent EF

do_update_binary(opts)

Update (Write) data of a transparent EF

do_update_binary_decoded(opts)

Encode + Update (Write) data of a transparent EF

decode_bin(raw_bin_data: bytearray) dict

Decode raw (binary) data into abstract representation.

A derived class would typically provide a _decode_bin() or _decode_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:

raw_bin_data – binary encoded data

Returns:

abstract_data; dict representing the decoded data

decode_hex(raw_hex_data: str) dict

Decode raw (hex string) data into abstract representation.

A derived class would typically provide a _decode_bin() or _decode_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:

raw_hex_data – hex-encoded data

Returns:

abstract_data; dict representing the decoded data

encode_bin(abstract_data: dict) bytearray

Encode abstract representation into raw (binary) data.

A derived class would typically provide an _encode_bin() or _encode_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:

abstract_data – dict representing the decoded data

Returns:

binary encoded data

encode_hex(abstract_data: dict) str

Encode abstract representation into raw (hex string) data.

A derived class would typically provide an _encode_bin() or _encode_hex() method for implementing this specifically for the given file. This function checks which of the method exists, add calls them (with conversion, as needed).

Parameters:

abstract_data – dict representing the decoded data

Returns:

hex string encoded data

pySim.filesystem.interpret_sw(sw_data: dict, sw: str)

Interpret a given status word.

Parameters:
  • sw_data – Hierarchical dict of status word matches

  • sw – status word to match (string of 4 hex digits)

Returns:

tuple of two strings (class_string, description)

pySim commands abstraction

pySim: SIM Card commands according to ISO 7816-4 and TS 11.11

class pySim.commands.SimCardCommands(transport: LinkBase, lchan_nr: int = 0)

Class providing methods for various card-specific commands such as SELECT, READ BINARY, etc. Historically one instance exists below CardBase, but with the introduction of multiple logical channels there can be multiple instances. The lchan number will then be patched into the CLA byte by the respective instance.

activate_file(fid: Hexstr) Tuple[Hexstr, SwHexstr]

Execute ACTIVATE FILE command as per TS 102 221 Section 11.1.15.

Parameters:

fid – file identifier as hex string

authenticate(rand: Hexstr, autn: Hexstr, context: str = '3g') Tuple[Hexstr, SwHexstr]

Execute AUTHENTICATE (USIM/ISIM).

Parameters:
  • rand – 16 byte random data as hex string (RAND)

  • autn – 8 byte Autentication Token (AUTN)

  • context – 16 byte random data (‘3g’ or ‘gsm’)

binary_size(ef: Hexstr | List[Hexstr]) int

Determine the size of given transparent file.

Parameters:

ef – string or list of strings indicating name or path of transparent EF

change_chv(chv_no: int, pin_code: Hexstr, new_pin_code: Hexstr) Tuple[Hexstr, SwHexstr]

Change a given CHV (Card Holder Verification == PIN)

Parameters:
  • chv_no – chv number (1=CHV1, 2=CHV2, …)

  • pin_code – current chv code as hex string

  • new_pin_code – new chv code as hex string

cla4lchan(cla: Hexstr) Hexstr

Compute the lchan-patched value of the given CLA value. If no CLA value is provided as argument, the lchan-patched version of the SimCardCommands._cla_byte value is used. Most commands will use the latter, while some wish to override it and can pass it as argument here.

property cla_byte: Hexstr

Return the (cached) patched default CLA byte for this card.

create_file(payload: Hexstr) Tuple[Hexstr, SwHexstr]

Execute CREEATE FILE command as per TS 102 222 Section 6.3

deactivate_file() Tuple[Hexstr, SwHexstr]

Execute DECATIVATE FILE command as per TS 102 221 Section 11.1.14.

delete_file(fid: Hexstr) Tuple[Hexstr, SwHexstr]

Execute DELETE FILE command as per TS 102 222 Section 6.4

disable_chv(chv_no: int, pin_code: Hexstr) Tuple[Hexstr, SwHexstr]

Disable a given CHV (Card Holder Verification == PIN)

Parameters:
  • chv_no – chv number (1=CHV1, 2=CHV2, …)

  • pin_code – current chv code as hex string

  • new_pin_code – new chv code as hex string

enable_chv(chv_no: int, pin_code: Hexstr) Tuple[Hexstr, SwHexstr]

Enable a given CHV (Card Holder Verification == PIN)

Parameters:
  • chv_no – chv number (1=CHV1, 2=CHV2, …)

  • pin_code – chv code as hex string

envelope(payload: Hexstr) Tuple[Hexstr, SwHexstr]

Send one ENVELOPE command to the SIM

Parameters:

payload – payload as hex string

fork_lchan(lchan_nr: int) SimCardCommands

Fork a per-lchan specific SimCardCommands instance off the current instance.

get_atr() Hexstr

Return the ATR of the currently inserted card.

manage_channel(mode: str = 'open', lchan_nr: int = 0) Tuple[Hexstr, SwHexstr]

Execute MANAGE CHANNEL command as per TS 102 221 Section 11.1.17.

Parameters:
  • mode – logical channel operation code (‘open’ or ‘close’)

  • lchan_nr – logical channel number (1-19, 0=assigned by UICC)

property max_cmd_len: int

Maximum length of the command apdu data section. Depends on secure channel protocol used.

read_binary(ef: Hexstr | List[Hexstr], length: int = None, offset: int = 0) Tuple[Hexstr, SwHexstr]

Execute READD BINARY.

Parameters:
  • ef – string or list of strings indicating name or path of transparent EF

  • length – number of bytes to read

  • offset – byte offset in file from which to start reading

read_record(ef: Hexstr | List[Hexstr], rec_no: int) Tuple[Hexstr, SwHexstr]

Execute READ RECORD.

Parameters:
  • ef – string or list of strings indicating name or path of linear fixed EF

  • rec_no – record number to read

record_count(ef: Hexstr | List[Hexstr]) int

Determine the number of records in given file.

Parameters:

ef – string or list of strings indicating name or path of linear fixed EF

record_size(ef: Hexstr | List[Hexstr]) int

Determine the record size of given file.

Parameters:

ef – string or list of strings indicating name or path of linear fixed EF

reset_card() Hexstr

Physically reset the card

resize_file(payload: Hexstr) Tuple[Hexstr, SwHexstr]

Execute RESIZE FILE command as per TS 102 222 Section 6.10

resume_uicc(token: Hexstr) Tuple[Hexstr, SwHexstr]

Send SUSPEND UICC (resume) to the card.

retrieve_data(ef: Hexstr | List[Hexstr], tag: int) Tuple[Hexstr, SwHexstr]

Execute RETRIEVE DATA, see also TS 102 221 Section 11.3.1.

Args

ef : string or list of strings indicating name or path of transparent EF tag : BER-TLV Tag of value to be retrieved

run_gsm(rand: Hexstr) Tuple[Hexstr, SwHexstr]

Execute RUN GSM ALGORITHM.

Parameters:

rand – 16 byte random data as hex string (RAND)

select_adf(aid: Hexstr) Tuple[Hexstr, SwHexstr]

Execute SELECT a given Applicaiton ADF.

Parameters:

aid – application identifier as hex string

select_file(fid: Hexstr) Tuple[Hexstr, SwHexstr]

Execute SELECT a given file by FID.

Parameters:

fid – file identifier as hex string

select_parent_df() Tuple[Hexstr, SwHexstr]

Execute SELECT to switch to the parent DF

select_path(dir_list: Hexstr | List[Hexstr]) List[Hexstr]

Execute SELECT for an entire list/path of FIDs.

Parameters:

dir_list – list of FIDs representing the path to select

Returns:

list of return values (FCP in hex encoding) for each element of the path

send_apdu(pdu: Hexstr) Tuple[Hexstr, SwHexstr]

Sends an APDU and auto fetch response data

Parameters:

pdu – string of hexadecimal characters (ex. “A0A40000023F00”)

Returns:

tuple(data, sw), where

data : string (in hex) of returned data (ex. “074F4EFFFF”) sw : string (in hex) of status word (ex. “9000”)

send_apdu_checksw(pdu: Hexstr, sw: SwMatchstr = '9000') Tuple[Hexstr, SwHexstr]

Sends an APDU and check returned SW

Parameters:
  • pdu – string of hexadecimal characters (ex. “A0A40000023F00”)

  • sw – string of 4 hexadecimal characters (ex. “9000”). The user may mask out certain digits using a ‘?’ to add some ambiguity if needed.

Returns:

tuple(data, sw), where

data : string (in hex) of returned data (ex. “074F4EFFFF”) sw : string (in hex) of status word (ex. “9000”)

send_apdu_constr(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.

Parameters:
  • cla – string (in hex) ISO 7816 class byte

  • ins – string (in hex) ISO 7816 instruction byte

  • p1 – string (in hex) ISO 7116 Parameter 1 byte

  • p2 – string (in hex) ISO 7116 Parameter 2 byte

  • cmd_cosntr – defining how to generate binary APDU command data

  • cmd_data – command data passed to cmd_constr

  • resp_cosntr – defining how to decode binary APDU response data

Returns:

Tuple of (decoded_data, sw)

send_apdu_constr_checksw(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.

Parameters:
  • cla – string (in hex) ISO 7816 class byte

  • ins – string (in hex) ISO 7816 instruction byte

  • p1 – string (in hex) ISO 7116 Parameter 1 byte

  • p2 – string (in hex) ISO 7116 Parameter 2 byte

  • cmd_cosntr – defining how to generate binary APDU command data

  • cmd_data – command data passed to cmd_constr

  • resp_cosntr – defining how to decode binary APDU response data

  • exp_sw – string (in hex) of status word (ex. “9000”)

Returns:

Tuple of (decoded_data, sw)

set_data(ef, tag: int, value: str, verify: bool = False, conserve: bool = False) Tuple[Hexstr, SwHexstr]

Execute SET DATA.

Args

ef : string or list of strings indicating name or path of transparent EF tag : BER-TLV Tag of value to be stored value : BER-TLV value to be stored

status() Tuple[Hexstr, SwHexstr]

Execute a STATUS command as per TS 102 221 Section 11.1.2.

suspend_uicc(min_len_secs: int = 60, max_len_secs: int = 43200) Tuple[int, Hexstr, SwHexstr]

Send SUSPEND UICC to the card.

Parameters:
  • min_len_secs – mimumum suspend time seconds

  • max_len_secs – maximum suspend time seconds

terminal_profile(payload: Hexstr) Tuple[Hexstr, SwHexstr]

Send TERMINAL PROFILE to card

Parameters:

payload – payload as hex string

terminate_card_usage() Tuple[Hexstr, SwHexstr]

Execute TERMINATE CARD USAGE command as per TS 102 222 Section 6.9

terminate_df(fid: Hexstr) Tuple[Hexstr, SwHexstr]

Execute TERMINATE DF command as per TS 102 222 Section 6.7

terminate_ef(fid: Hexstr) Tuple[Hexstr, SwHexstr]

Execute TERMINATE EF command as per TS 102 222 Section 6.8

try_select_path(dir_list: List[Hexstr]) List[Tuple[Hexstr, SwHexstr]]

Try to select a specified path

Parameters:

dir_list – list of hex-string FIDs

unblock_chv(chv_no: int, puk_code: str, pin_code: str)

Unblock a given CHV (Card Holder Verification == PIN)

Parameters:
  • chv_no – chv number (1=CHV1, 2=CHV2, …)

  • puk_code – puk code as hex string

  • pin_code – new chv code as hex string

update_binary(ef: Hexstr | List[Hexstr], data: Hexstr, offset: int = 0, verify: bool = False, conserve: bool = False) Tuple[Hexstr, SwHexstr]

Execute UPDATE BINARY.

Parameters:
  • ef – string or list of strings indicating name or path of transparent EF

  • data – hex string of data to be written

  • offset – byte offset in file from which to start writing

  • verify – Whether or not to verify data after write

update_record(ef: Hexstr | List[Hexstr], rec_no: int, data: Hexstr, force_len: bool = False, verify: bool = False, conserve: bool = False, leftpad: bool = False) Tuple[Hexstr, SwHexstr]

Execute UPDATE RECORD.

Parameters:
  • ef – string or list of strings indicating name or path of linear fixed EF

  • rec_no – record number to read

  • data – hex string of data to be written

  • force_len – enforce record length by using the actual data length

  • verify – verify data by re-reading the record

  • conserve – read record and compare it with data, skip write on match

  • leftpad – apply 0xff padding from the left instead from the right side.

verify_chv(chv_no: int, code: Hexstr) Tuple[Hexstr, SwHexstr]

Verify a given CHV (Card Holder Verification == PIN)

Parameters:
  • chv_no – chv number (1=CHV1, 2=CHV2, …)

  • code – chv code as hex string

pySim.commands.cla_with_lchan(cla_byte: Hexstr, lchan_nr: int) Hexstr

Embed a logical channel number into the hex-string encoded CLA value.

pySim.commands.lchan_nr_to_cla(cla: int, lchan_nr: int) int

Embed a logical channel number into the CLA byte.

pySim Transport

The pySim.transport classes implement specific ways how to communicate with a SIM card. A “transport” provides ways to transceive APDUs with the card.

The most commonly used transport uses the PC/SC interface to utilize a variety of smart card interfaces (“readers”).

Transport base class

pySim: PCSC reader transport link base

class pySim.transport.LinkBase(sw_interpreter=None, apdu_tracer: ApduTracer | None = None, proactive_handler: ProactiveHandler | None = None)

Base class for link/transport to card.

abstract connect()

Connect to a card immediately

abstract disconnect()

Disconnect from card

abstract reset_card()

Resets the card (power down/up)

send_apdu(pdu: Hexstr) Tuple[Hexstr, SwHexstr]

Sends an APDU and auto fetch response data

Parameters:

pdu – string of hexadecimal characters (ex. “A0A40000023F00”)

Returns:

tuple(data, sw), where

data : string (in hex) of returned data (ex. “074F4EFFFF”) sw : string (in hex) of status word (ex. “9000”)

send_apdu_checksw(pdu: Hexstr, sw: SwMatchstr = '9000') Tuple[Hexstr, SwHexstr]

Sends an APDU and check returned SW

Parameters:
  • pdu – string of hexadecimal characters (ex. “A0A40000023F00”)

  • sw – string of 4 hexadecimal characters (ex. “9000”). The user may mask out certain digits using a ‘?’ to add some ambiguity if needed.

Returns:

tuple(data, sw), where

data : string (in hex) of returned data (ex. “074F4EFFFF”) sw : string (in hex) of status word (ex. “9000”)

send_apdu_raw(pdu: Hexstr) Tuple[Hexstr, SwHexstr]

Sends an APDU with minimal processing

Parameters:

pdu – string of hexadecimal characters (ex. “A0A40000023F00”)

Returns:

tuple(data, sw), where

data : string (in hex) of returned data (ex. “074F4EFFFF”) sw : string (in hex) of status word (ex. “9000”)

set_sw_interpreter(interp)

Set an (optional) status word interpreter.

abstract wait_for_card(timeout: int | None = None, newcardonly: bool = False)

Wait for a card and connect to it

Parameters:
  • timeout – Maximum wait time in seconds (None=no timeout)

  • newcardonly – Should we wait for a new card, or an already inserted one ?

class pySim.transport.ProactiveHandler

Abstract base class representing the interface of some code that handles the proactive commands, as returned by the card in responses to the FETCH command.

receive_fetch(pcmd: ProactiveCommand)

Default handler for not otherwise handled proactive commands.

pySim.transport.argparse_add_reader_args(arg_parser: ArgumentParser)

Add all reader related arguments to the given argparse.Argumentparser instance.

pySim.transport.init_reader(opts, **kwargs) LinkBase

Init card reader driver

calypso / OsmocomBB transport

This allows the use of the SIM slot of an OsmocomBB compatible phone with the TI Calypso chipset, using the L1CTL interface to talk to the layer1.bin firmware on the phone.

Transport Link for Calypso based phones.

connect()

Connect to a card immediately

disconnect()

Disconnect from card

reset_card()

Resets the card (power down/up)

wait_for_card(timeout: int | None = None, newcardonly: bool = False)

Wait for a card and connect to it

Parameters:
  • timeout – Maximum wait time in seconds (None=no timeout)

  • newcardonly – Should we wait for a new card, or an already inserted one ?

AT-command Modem transport

This transport uses AT commands of a cellular modem in order to get access to the SIM card inserted in such a modem.

Transport Link for 3GPP TS 27.007 compliant modems.

connect()

Connect to a card immediately

disconnect()

Disconnect from card

reset_card()

Resets the card (power down/up)

wait_for_card(timeout: int | None = None, newcardonly: bool = False)

Wait for a card and connect to it

Parameters:
  • timeout – Maximum wait time in seconds (None=no timeout)

  • newcardonly – Should we wait for a new card, or an already inserted one ?

PC/SC transport

PC/SC is the standard API for accessing smart card interfaces on all major operating systems, including the MS Windows Family, OS X as well as Linux / Unix OSs.

pySim: PCSC reader transport link.

connect()

Connect to a card immediately

disconnect()

Disconnect from card

reset_card()

Resets the card (power down/up)

wait_for_card(timeout: int | None = None, newcardonly: bool = False)

Wait for a card and connect to it

Parameters:
  • timeout – Maximum wait time in seconds (None=no timeout)

  • newcardonly – Should we wait for a new card, or an already inserted one ?

Serial/UART transport

This transport implements interfacing smart cards via very simplistic UART readers. These readers basically wire together the Rx+Tx pins of a RS232 UART, provide a fixed crystal oscillator for clock, and operate the UART at 9600 bps. These readers are sometimes called Phoenix.

pySim: Transport Link for serial (RS232) based readers included with simcard

connect()

Connect to a card immediately

disconnect()

Disconnect from card

reset_card()

Resets the card (power down/up)

wait_for_card(timeout: int | None = None, newcardonly: bool = False)

Wait for a card and connect to it

Parameters:
  • timeout – Maximum wait time in seconds (None=no timeout)

  • newcardonly – Should we wait for a new card, or an already inserted one ?

pySim construct utilities

Utility code related to the integration of the ‘construct’ declarative parser.

class pySim.construct.BcdAdapter(subcon)

convert a bytes() type to a string of BCD nibbles.

pySim.construct.BitsRFU(n=1)

Field that packs Reserved for Future Use (RFU) bit(s) as defined in TS 31.101 Sec. “3.4 Coding Conventions”

Use this for (currently) unused/reserved bits whose contents should be initialized automatically but should not be cleared in the future or when restoring read data (unlike padding).

Parameters:

n (Integer) – Number of bits (default: 1)

pySim.construct.BytesRFU(n=1)

Field that packs Reserved for Future Use (RFU) byte(s) as defined in TS 31.101 Sec. “3.4 Coding Conventions”

Use this for (currently) unused/reserved bytes whose contents should be initialized automatically but should not be cleared in the future or when restoring read data (unlike padding).

Parameters:

n (Integer) – Number of bytes (default: 1)

class pySim.construct.GreedyInteger(signed=False, swapped=False, minlen=0)

A variable-length integer implementation, think of combining GrredyBytes with BytesInteger.

class pySim.construct.GsmOrUcs2Adapter(subcon)

Try to encode into a GSM 03.38 string; if that fails, fall back to UCS-2 as described in TS 102 221 Annex A.

pySim.construct.GsmOrUcs2String(n)

GSM 03.38 or UCS-2 (TS 102 221 Annex A) encoded byte string of fixed length n. Encoder appends padding bytes (b’xff’) to maintain length. Decoder removes those trailing bytes.

Exceptions are raised for invalid characters and length excess.

Parameters:

n (Integer) – Fixed length of the encoded byte string

pySim.construct.GsmString(n)

GSM 03.38 encoded byte string of fixed length n. Encoder appends padding bytes (b’xff’) to maintain length. Decoder removes those trailing bytes.

Exceptions are raised for invalid characters and length excess.

Parameters:

n (Integer) – Fixed length of the encoded byte string

class pySim.construct.GsmStringAdapter(subcon, codec='gsm03.38', err='strict')

Convert GSM 03.38 encoded bytes to a string.

class pySim.construct.HexAdapter(subcon)

convert a bytes() type to a string of hex nibbles.

class pySim.construct.InvertAdapter(subcon)

inverse logic (false->true, true->false).

class pySim.construct.Ipv4Adapter(subcon)

Encoder converts from 4 bytes to string representation (A.B.C.D). Decoder converts from string representation (A.B.C.D) to four bytes.

class pySim.construct.Ipv6Adapter(subcon)

Encoder converts from 16 bytes to string representation. Decoder converts from string representation to 16 bytes.

class pySim.construct.MultiplyAdapter(subcon, multiplicator)

Decoder multiplies by multiplicator Encoder divides by multiplicator

Parameters:
  • subcon – Subconstruct as defined by construct library

  • multiplier – Multiplier to apply to raw encoded value

class pySim.construct.PlmnAdapter(subcon)

convert a bytes(3) type to BCD string like 262-02 or 262-002.

class pySim.construct.Rpad(subcon, pattern=b'\xff', num_per_byte=1)

Encoder appends padding bytes (b’xff’) or characters up to target size. Decoder removes trailing padding bytes/characters.

Parameters:
  • subcon – Subconstruct as defined by construct library

  • pattern – set padding pattern (default: b’xff’)

  • num_per_byte – number of ‘elements’ per byte. E.g. for hex nibbles: 2

class pySim.construct.StripTrailerAdapter(subcon, total_length: int, default_value=b'\x00', min_len=1)

Encoder removes all trailing bytes matching the default_value Decoder pads input data up to total_length with default_value

This is used in constellations like “FlagsEnum(StripTrailerAdapter(GreedyBytes, 3), …” where you have a bit-mask that may have 1, 2 or 3 bytes, depending on whether or not any of the LSBs are actually set.

class pySim.construct.Ucs2Adapter(subcon)

convert a bytes() type that contains UCS2 encoded characters encoded as defined in TS 102 221 Annex A to normal python string representation (and back).

class pySim.construct.Utf8Adapter(subcon)

convert a bytes() type that contains utf8 encoded text to human readable text.

pySim.construct.build_construct(c, decoded_data, context: dict = {})

Helper function to handle total_len.

pySim.construct.filter_dict(d, exclude_prefix='_')

filter the input dict to ensure no keys starting with ‘exclude_prefix’ remain.

pySim.construct.normalize_construct(c, exclude_prefix: str = '_')

Convert a construct specific type to a related base type, mostly useful so we can serialize it.

pySim.construct.parse_construct(c, raw_bin_data: bytes, length: int | None = None, exclude_prefix: str = '_', context: dict = {})

Helper function to wrap around normalize_construct() and filter_dict().

pySim TLV utilities

object-oriented TLV parser/encoder library.

class pySim.tlv.BER_TLV_IE(**kwargs)

TLV_IE formatted as ASN.1 BER described in ITU-T X.690 8.1.2.

class pySim.tlv.COMPR_TLV_IE(**kwargs)

TLV_IE formated as COMPREHENSION-TLV as described in ETSI TS 101 220.

class pySim.tlv.DGI_TLV_IE(**kwargs)

TLV_IE formated as GlobalPlatform Systems Scripting Language Specification v1.1.0 Annex B.

class pySim.tlv.IE(**kwargs)

Base class for various Information Elements. We understand the notion of a hierarchy of IEs on top of the Transcodable class.

from_bytes(do: bytes, context: dict = {})

Parse the value part from binary bytes to internal representation.

from_dict(decoded: dict)

Set the IE internal decoded representation to data from the argument. If this is a nested IE, the child IE instance list is re-created.

is_constructed()

Is this IE constructed by further nested IEs?

to_bytes(context: dict = {}) bytes

Convert the internal representation of the value part to binary bytes.

to_dict()

Return a JSON-serializable dict representing the [nested] IE data.

abstract to_ie(context: dict = {}) bytes

Convert the internal representation to entire IE including IE header.

class pySim.tlv.TLV_IE(**kwargs)

Abstract base class for various TLV type Information Elements.

to_ie(context: dict = {})

Convert the internal representation to entire IE including IE header.

to_tlv(context: dict = {})

Convert the internal representation to binary TLV bytes.

class pySim.tlv.TLV_IE_Collection(desc=None, **kwargs)

A TLV_IE_Collection consists of multiple TLV_IE classes identified by their tags. A given encoded DO may contain any of them in any order, and may contain multiple instances of each DO.

from_bytes(binary: bytes, context: dict = {}) List[TLV_IE]

Create a list of TLV_IEs from the collection based on binary input data. :param binary: binary bytes of encoded data

Returns:

list of instances of TLV_IE sub-classes containing parsed data

from_dict(decoded: List[dict]) List[TLV_IE]

Create a list of TLV_IE instances from the collection based on an array of dicts, where they key indicates the name of the TLV_IE subclass to use.

class pySim.tlv.TlvCollectionMeta(name, bases, namespace, **kwargs)

Metaclass which we use to set some class variables at the time of defining a subclass. This allows us to create subclasses for each Collection type, where the class represents fixed parameters like the nested IE classes and instances of it represent the actual TLV data.

class pySim.tlv.TlvMeta(name, bases, namespace, **kwargs)

Metaclass which we use to set some class variables at the time of defining a subclass. This allows us to create subclasses for each TLV/IE type, where the class represents fixed parameters like the tag/type and instances of it represent the actual TLV data.

class pySim.tlv.Transcodable
from_bytes(do: bytes, context: dict = {})

Convert from binary bytes to internal representation. Store the decoded result in the internal state and return it.

to_bytes(context: dict = {}) bytes

Convert from internal representation to binary bytes. Store the binary result in the internal state and return it.

pySim.tlv.flatten_dict_lists(inp)

hierarchically flatten each list-of-dicts into a single dict. This is useful to make the output of hierarchical TLV decoder structures flatter and more easy to read.

pySim utility functions

pySim: various utilities

class pySim.utils.CardCommand(name, ins, cla_list=None, desc=None)

A single card command / instruction.

match_cla(cla)

Does the given CLA match the CLA list of the command?.

class pySim.utils.CardCommandSet(name, cmds=[])

A set of card instructions, typically specified within one spec.

lookup(ins, cla=None)

look-up the command within the CommandSet.

class pySim.utils.DataObject(name: str, desc: str | None = None, tag: int | None = None)

A DataObject (DO) in the sense of ISO 7816-4. Contrary to ‘normal’ TLVs where one simply has any number of different TLVs that may occur in any order at any point, ISO 7816 has the habit of specifying TLV data but with very spcific ordering, or specific choices of tags at specific points in a stream. This class tries to represent this.

Parameters:
  • name – A brief, all-lowercase, underscore separated string identifier

  • desc – A human-readable description of what this DO represents

  • tag – The tag associated with this DO

decode(binary: bytes) Tuple[dict, bytes]

Decode a single DOs from the input data. :param binary: binary bytes of encoded data

Returns:

tuple of (decoded_result, binary_remainder)

abstract from_bytes(do: bytes)

Parse the value part of the DO into the internal state of this instance. :param do: binary encoded bytes

from_tlv(do: bytes) bytes

Parse binary TLV representation into internal state. The resulting decoded representation is _not_ returned, but just internalized in the object instance! :param do: input bytes containing TLV-encoded representation

Returns:

bytes remaining at end of ‘do’ after parsing one TLV/DO.

abstract to_bytes() bytes

Encode the internal state of this instance into the TLV value part. :returns: binary bytes encoding the internal state

to_dict() dict

Return a dict in form “name: decoded_value”

to_tlv() bytes

Encode internal representation to binary TLV. :returns: bytes encoded in TLV format.

class pySim.utils.DataObjectChoice(name: str, desc: str | None = None, members=None)

One Data Object from within a choice, identified by its tag. This means that exactly one member of the choice must occur, and which one occurs depends on the tag.

decode(binary: bytes) Tuple[dict, bytes]

Decode a single DOs from the choice based on the tag. :param binary: binary bytes of encoded data

Returns:

tuple of (decoded_result, binary_remainder)

class pySim.utils.DataObjectCollection(name: str, desc: str | None = None, members=None)

A DataObjectCollection consits of multiple Data Objects identified by their tags. A given encoded DO may contain any of them in any order, and may contain multiple instances of each DO.

decode(binary: bytes) Tuple[List, bytes]

Decode any number of DOs from the collection until the end of the input data, or uninitialized memory (0xFF) is found. :param binary: binary bytes of encoded data

Returns:

tuple of (decoded_result, binary_remainder)

class pySim.utils.DataObjectSequence(name: str, desc: str | None = None, sequence=None)

A sequence of DataObjects or DataObjectChoices. This allows us to express a certain ordered sequence of DOs or choices of DOs that have to appear as per the specification. By wrapping them into this formal DataObjectSequence, we can offer convenience methods for encoding or decoding an entire sequence.

decode(binary: bytes) Tuple[list, bytes]

Decode a sequence by calling the decoder of each element in the sequence. :param binary: binary bytes of encoded data

Returns:

tuple of (decoded_result, binary_remainder)

decode_multi(do: bytes) Tuple[list, bytes]

Decode multiple occurrences of the sequence from the binary input data. :param do: binary input data to be decoded

Returns:

list of results of the decoder of this sequences

encode(decoded) bytes

Encode a sequence by calling the encoder of each element in the sequence.

encode_multi(decoded) bytes

Encode multiple occurrences of the sequence from the decoded input data. :param decoded: list of json-serializable input data; one sequence per list item

Returns:

binary encoded output data

class pySim.utils.JsonEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)

Extend the standard library JSONEncoder with support for more types.

Constructor for JSONEncoder, with sensible defaults.

If skipkeys is false, then it is a TypeError to attempt encoding of keys that are not str, int, float or None. If skipkeys is True, such items are simply skipped.

If ensure_ascii is true, the output is guaranteed to be str objects with all incoming non-ASCII characters escaped. If ensure_ascii is false, the output can contain non-ASCII characters.

If check_circular is true, then lists, dicts, and custom encoded objects will be checked for circular references during encoding to prevent an infinite recursion (which would cause an RecursionError). Otherwise, no such check takes place.

If allow_nan is true, then NaN, Infinity, and -Infinity will be encoded as such. This behavior is not JSON specification compliant, but is consistent with most JavaScript based encoders and decoders. Otherwise, it will be a ValueError to encode such floats.

If sort_keys is true, then the output of dictionaries will be sorted by key; this is useful for regression tests to ensure that JSON serializations can be compared on a day-to-day basis.

If indent is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. None is the most compact representation.

If specified, separators should be an (item_separator, key_separator) tuple. The default is (’, ‘, ‘: ‘) if indent is None and (‘,’, ‘: ‘) otherwise. To get the most compact JSON representation, you should specify (‘,’, ‘:’) to eliminate whitespace.

If specified, default is a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError.

default(o)

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return JSONEncoder.default(self, o)
class pySim.utils.TL0_DataObject(name: str, desc: str, tag: int, val=None)

Data Object that has Tag, Len=0 and no Value part.

Parameters:
  • name – A brief, all-lowercase, underscore separated string identifier

  • desc – A human-readable description of what this DO represents

  • tag – The tag associated with this DO

from_bytes(binary: bytes)

Parse the value part of the DO into the internal state of this instance. :param do: binary encoded bytes

to_bytes() bytes

Encode the internal state of this instance into the TLV value part. :returns: binary bytes encoding the internal state

pySim.utils.all_subclasses(cls) set

Recursively get all subclasses of a specified class

pySim.utils.auto_int(x)

Helper function for argparse to accept hexadecimal integers.

pySim.utils.b2h(b: bytearray) Hexstr

convert from a sequence of bytes to a string of hex nibbles

pySim.utils.bertlv_encode_len(length: int) bytes

Encode a single Length value according to ITU-T X.690 8.1.3; only the definite form is supported here. :param length: length value to be encoded

Returns:

binary output data of BER-TLV length field

pySim.utils.bertlv_encode_tag(t) bytes

Encode a single Tag value according to ITU-T X.690 8.1.2

pySim.utils.bertlv_parse_len(binary: bytes) Tuple[int, bytes]

Parse a single Length value according to ITU-T X.690 8.1.3; only the definite form is supported here. :param binary: binary input data of BER-TLV length field

Returns:

Tuple of (length, remainder)

pySim.utils.bertlv_parse_one(binary: bytes) Tuple[dict, int, bytes, bytes]

Parse a single TLV IE at the start of the given binary data. :param binary: binary input data of BER-TLV length field

Returns:

dict, len:int, remainder:bytes)

Return type:

Tuple of (tag

pySim.utils.bertlv_parse_tag(binary: bytes) Tuple[dict, bytes]

Parse a single Tag value according to ITU-T X.690 8.1.2 :param binary: binary input data of BER-TLV length field

Returns:

int, constructed:bool, tag:int}, remainder:bytes)

Return type:

Tuple of ({class

pySim.utils.bertlv_parse_tag_raw(binary: bytes) Tuple[int, bytes]

Get a single raw Tag from start of input according to ITU-T X.690 8.1.2 :param binary: binary input data of BER-TLV length field

Returns: Tuple of (tag:int, remainder:bytes)

pySim.utils.boxed_heading_str(heading, width=80)

Generate a string that contains a boxed heading.

pySim.utils.calculate_luhn(cc) int

Calculate Luhn checksum used in e.g. ICCID and IMEI

pySim.utils.comprehensiontlv_encode_tag(tag) bytes

Encode a single Tag according to ETSI TS 101 220 Section 7.1.1

pySim.utils.comprehensiontlv_parse_one(binary: bytes) Tuple[dict, int, bytes, bytes]

Parse a single TLV IE at the start of the given binary data. :param binary: binary input data of BER-TLV length field

Returns:

dict, len:int, remainder:bytes)

Return type:

Tuple of (tag

pySim.utils.comprehensiontlv_parse_tag(binary: bytes) Tuple[dict, bytes]

Parse a single Tag according to ETSI TS 101 220 Section 7.1.1

pySim.utils.comprehensiontlv_parse_tag_raw(binary: bytes) Tuple[int, bytes]

Parse a single Tag according to ETSI TS 101 220 Section 7.1.1

pySim.utils.dec_imsi(ef: Hexstr) str | None

Converts an EF value to the IMSI string representation

pySim.utils.dec_msisdn(ef_msisdn: Hexstr) Tuple[int, int, str | None] | None

Decode MSISDN from EF.MSISDN or EF.ADN (same structure). See 3GPP TS 31.102, section 4.2.26 and 4.4.2.3.

pySim.utils.derive_mcc(digit1: int, digit2: int, digit3: int) int

Derive decimal representation of the MCC (Mobile Country Code) from three given digits.

pySim.utils.derive_milenage_opc(ki_hex: Hexstr, op_hex: Hexstr) Hexstr

Run the milenage algorithm to calculate OPC from Ki and OP

pySim.utils.derive_mnc(digit1: int, digit2: int, digit3: int = 15) int

Derive decimal representation of the MNC (Mobile Network Code) from two or (optionally) three given digits.

pySim.utils.dgi_encode_len(length: int) bytes

Encode a single Length value according to GlobalPlatform Systems Scripting Language Specification v1.1.0 Annex B. :param length: length value to be encoded

Returns:

binary output data of encoded length field

pySim.utils.dgi_parse_len(binary: bytes) Tuple[int, bytes]

Parse a single Length value according to GlobalPlatform Systems Scripting Language Specification v1.1.0 Annex B. :param binary: binary input data of BER-TLV length field

Returns:

Tuple of (length, remainder)

pySim.utils.enc_imsi(imsi: str)

Converts a string IMSI into the encoded value of the EF

pySim.utils.enc_msisdn(msisdn: str, npi: int = 1, ton: int = 3) Hexstr

Encode MSISDN as LHV so it can be stored to EF.MSISDN. See 3GPP TS 31.102, section 4.2.26 and 4.4.2.3. (The result will not contain the optional Alpha Identifier at the beginning.)

Default NPI / ToN values:
  • NPI: ISDN / telephony numbering plan (E.164 / E.163),

  • ToN: network specific or international number (if starts with ‘+’).

pySim.utils.enc_plmn(mcc: Hexstr, mnc: Hexstr) Hexstr

Converts integer MCC/MNC into 3 bytes for EF

pySim.utils.expand_hex(hexstring, length)
Expand a given hexstring to a specified length by replacing “.” or “..”

with a filler that is derived from the neighboring nibbles respective bytes. Usually this will be the nibble respective byte before “.” or “..”, execpt when the string begins with “.” or “..”, then the nibble respective byte after “.” or “..” is used.”. In case the string cannot be expanded for some reason, the input string is returned unmodified.

Parameters:
  • hexstring – hexstring to expand

  • length – desired length of the resulting hexstring.

Returns:

expanded hexstring

pySim.utils.get_addr_type(addr)

Validates the given address and returns it’s type (FQDN or IPv4 or IPv6) Return: 0x00 (FQDN), 0x01 (IPv4), 0x02 (IPv6), None (Bad address argument given)

TODO: Handle IPv6

pySim.utils.h2b(s: Hexstr) bytearray

convert from a string of hex nibbles to a sequence of bytes

pySim.utils.h2i(s: Hexstr) List[int]

convert from a string of hex nibbles to a list of integers

pySim.utils.h2s(s: Hexstr) str

convert from a string of hex nibbles to an ASCII string

pySim.utils.i2h(s: List[int]) Hexstr

convert from a list of integers to a string of hex nibbles

pySim.utils.i2s(s: List[int]) str

convert from a list of integers to an ASCII string

pySim.utils.is_decimal(instr: str) str

Method that can be used as ‘type’ in argparse.add_argument() to validate the value consists of an even sequence of decimal digits only.

pySim.utils.is_hex(string: str, minlen: int = 2, maxlen: int | None = None) bool

Check if a string is a valid hexstring

pySim.utils.is_hexstr(instr: str) str

Method that can be used as ‘type’ in argparse.add_argument() to validate the value consists of an even sequence of hexadecimal digits only.

pySim.utils.is_hexstr_or_decimal(instr: str) str

Method that can be used as ‘type’ in argparse.add_argument() to validate the value consists of [hexa]decimal digits only.

pySim.utils.lpad(s: str, l: int, c='f') str

pad string on the left side. :param s: string to pad :param l: total length to pad to :param c: padding character

Returns:

String ‘s’ padded with as many ‘c’ as needed to reach total length of ‘l’

pySim.utils.mcc_from_imsi(imsi: str) str | None

Derive the MCC (Mobile Country Code) from the first three digits of an IMSI

pySim.utils.mnc_from_imsi(imsi: str, long: bool = False) str | None

Derive the MNC (Mobile Country Code) from the 4th to 6th digit of an IMSI

pySim.utils.rpad(s: str, l: int, c='f') str

pad string on the right side. :param s: string to pad :param l: total length to pad to :param c: padding character

Returns:

String ‘s’ padded with as many ‘c’ as needed to reach total length of ‘l’

pySim.utils.s2h(s: str) Hexstr

convert from an ASCII string to a string of hex nibbles

pySim.utils.sanitize_pin_adm(pin_adm, pin_adm_hex=None) Hexstr

The ADM pin can be supplied either in its hexadecimal form or as ascii string. This function checks the supplied opts parameter and returns the pin_adm as hex encoded string, regardless in which form it was originally supplied by the user

pySim.utils.str_sanitize(s: str) str

replace all non printable chars, line breaks and whitespaces, with ‘ ‘, make sure that there are no whitespaces at the end and at the beginning of the string.

Parameters:

s – string to sanitize

Returns:

filtered result of string ‘s’

pySim.utils.sw_match(sw: str, pattern: str) bool

Match given SW against given pattern.

pySim.utils.swap_nibbles(s: Hexstr) Hexstr

swap the nibbles in a hex string

pySim.utils.tabulate_str_list(str_list, width: int = 79, hspace: int = 2, lspace: int = 1, align_left: bool = True) str

Pretty print a list of strings into a tabulated form.

Parameters:
  • width – total width in characters per line

  • space – horizontal space between cells

  • lspace – number of spaces before row

  • align_lef – Align text to the left side

Returns:

multi-line string containing formatted table

pySim.utils.verify_luhn(digits: str)

Verify the Luhn check digit; raises ValueError if it is incorrect.

pySim exceptions

pySim: Exceptions

exception pySim.exceptions.NoCardError

No card was found in the reader.

exception pySim.exceptions.ProtocolError

Some kind of protocol level error interfacing with the card.

exception pySim.exceptions.ReaderError

Some kind of general error with the card reader.

exception pySim.exceptions.SwMatchError(sw_actual: str, sw_expected: str, rs=None)

Raised when an operation specifies an expected SW but the actual SW from the card doesn’t match.

Parameters:
  • sw_actual – the SW we actually received from the card (4 hex digits)

  • sw_expected – the SW we expected to receive from the card (4 hex digits)

  • rs – interpreter class to convert SW to string

pySim card_handler

pySim: card handler utilities. A ‘card handler’ is some method by which cards can be inserted/removed into the card reader. For normal smart card readers, this has to be done manually. However, there are also automatic card feeders.

class pySim.card_handler.CardHandler(sl: LinkBase)

Manual card handler: User is prompted to insert/remove card from the reader.

class pySim.card_handler.CardHandlerAuto(sl: LinkBase, config_file: str)

Automatic card handler: A machine is used to handle the cards.

class pySim.card_handler.CardHandlerBase(sl: LinkBase)

Abstract base class representing a mechanism for card insertion/removal.

done()

Method called when pySim failed to program a card. Move card to ‘good’ batch.

error()

Method called when pySim failed to program a card. Move card to ‘bad’ batch.

get(first: bool = False)

Method called when pySim needs a new card to be inserted.

Parameters:

first – set to true when the get method is called the first time. This is required to prevent blocking when a card is already inserted into the reader. The reader API would not recognize that card as “new card” until it would be removed and re-inserted again.

pySim card_key_provider

Obtaining card parameters (mostly key data) from external source.

This module contains a base class and a concrete implementation of obtaining card key material (or other card-individual parameters) from an external data source.

This is used e.g. to keep PIN/PUK data in some file on disk, avoiding the need of manually entering the related card-individual data on every operation with pySim-shell.

class pySim.card_key_provider.CardKeyProvider

Base class, not containing any concrete implementation.

abstract get(fields: List[str], key: str, value: str) Dict[str, str]

Get multiple card-individual fields for identified card.

Parameters:
  • fields – list of valid field names such as ‘ADM1’, ‘PIN1’, … which are to be obtained

  • key – look-up key to identify card data, such as ‘ICCID’

  • value – value for look-up key to identify card data

Returns:

dictionary of {field, value} strings for each requested field from ‘fields’

get_field(field: str, key: str = 'ICCID', value: str = '') str | None

get a single field from CSV file using a specified key/value pair

class pySim.card_key_provider.CardKeyProviderCsv(filename: str)

Card key provider implementation that allows to query against a specified CSV file

Parameters:

filename – file name (path) of CSV file containing card-individual key/data

get(fields: List[str], key: str, value: str) Dict[str, str]

Get multiple card-individual fields for identified card.

Parameters:
  • fields – list of valid field names such as ‘ADM1’, ‘PIN1’, … which are to be obtained

  • key – look-up key to identify card data, such as ‘ICCID’

  • value – value for look-up key to identify card data

Returns:

dictionary of {field, value} strings for each requested field from ‘fields’

pySim.card_key_provider.card_key_provider_get(fields, key: str, value: str, provider_list=[]) Dict[str, str]

Query all registered card data providers for card-individual [key] data.

Parameters:
  • fields – list of valid field names such as ‘ADM1’, ‘PIN1’, … which are to be obtained

  • key – look-up key to identify card data, such as ‘ICCID’

  • value – value for look-up key to identify card data

  • provider_list – override the list of providers from the global default

Returns:

dictionary of {field, value} strings for each requested field from ‘fields’

pySim.card_key_provider.card_key_provider_get_field(field: str, key: str, value: str, provider_list=[]) str | None

Query all registered card data providers for a single field.

Parameters:
  • field – name valid field such as ‘ADM1’, ‘PIN1’, … which is to be obtained

  • key – look-up key to identify card data, such as ‘ICCID’

  • value – value for look-up key to identify card data

  • provider_list – override the list of providers from the global default

Returns:

dictionary of {field, value} strings for the requested field

pySim.card_key_provider.card_key_provider_register(provider: CardKeyProvider, provider_list=[])

Register a new card key provider.

Parameters:
  • provider – the to-be-registered provider

  • provider_list – override the list of providers from the global default