ISO7816 API

This API provides support for ISO7816 support with Scaffold.

class scaffold.iso7816.Smartcard(scaffold: Scaffold = None)

Class for smartcard testing with Scaffold board and API. The following IOs are used:

  • D0: ISO-7816 IO

  • D1: ISO-7816 nRST

  • D2: ISO-7816 CLK

  • D3: Socket card contactor sense

scaffold.Scaffold class has ISO-7816 peripheral support, but it is very limited. This class enables full support to ISO-7816 by managing ATR, convention convertion, T=0 or T=1 protocols, etc.

Variables:
  • atr (bytes) – ATR received from card after reset.

  • convention (Convention) – Communication convention between card and terminal. Updated when first byte TS of ATR is received.

  • protocols (set) – Communication protocols found in ATR. This set contains integers, for instance 0 if T=0 is supported, 1 if T=1 is supported…

__init__(scaffold: Scaffold = None)

Configure a Scaffold board for use with smartcards.

Parameters:

scaffold – Board instance which will be configured as a smartcard reader. scaffold.Scaffold instance.

apdu(the_apdu: bytes | str, trigger: str = '') bytes

Send an APDU to the smartcard and retrieve the response.

If only T=1 protocol is supported, this method use transmit_block and receive_block to send the APDU by sending information blocks.

Parameters:
  • the_apdu – APDU to be sent. str hexadecimal strings are allowed, but user should consider using the apdu_str() method instead.

  • trigger – If ‘a’ is in this string, trigger is raised after ISO-7816 header is sent in T=0, and cleared when the following response byte arrives. If ‘b’ is in this string, trigger is raised after data field has been transmitted in T=0, and cleared when the next response byte is received. If T=1, both ‘a’ and ‘b’ will raise trigger after the I-block has been transmitted, and will be cleared when first byte of next block is received.

Raises:
  • ValueError – if APDU data is invalid.

  • RuntimeError – if the received procedure byte is invalid in T=0, or if neither T=0 and T=1 protocols are supported by the card.

  • T1RedundancyCodeError – If LRC or CRC is wrong in T=1 protocol.

Returns:

Response data, with status word.

apdu_str(the_apdu: str) str

Same as apdu() function, with str argument and return type for convenience.

Parameters:

the_apdu – APDU to be sent, as an hexadecimal string.

Returns:

Response from the card, as a lowercase hexadecimal string without spaces.

calculate_edc(data: bytes) bytes

Calculate expected error detection code for a block. Depending on self.t1_redundancy_code LRC (1 bytes) or CRC (2 bytes) is calculated.

Parameters:

data – Input data for the error detection code calculation. Includes all bytes of the block excepted the LRC or CRC bytes.

Returns:

ECC bytes at the end of the block.

property card_inserted

True if a card is inserted, False otherwise. Card insertion is detected with a mecanical switch connected to D3 of Scaffold.

find_info(allow_web_download: bool = False) List[str] | None

Parse the smartcard ATR list database available at http://ludovic.rousseau.free.fr/softwares/pcsc-tools/smartcard_list.txt and try to match the current ATR to retrieve more info about the card.

The database file cannot be embedded in the library because it uses GPL and not LGPL license. On debian systems, this file is provided in the pcsc-tools package.

Parameters:

allow_web_download – If enabled, allow the method to download the database from the web as a fallback when it is missing from the system.

Returns:

A list of str, where each item is an information line about the card. Return None if the ATR did not match any entry in the database.

Raises:

NoATRDatabase – When database file is missing and download is not allowed, or when database file is missing and download failed.

pps(pps1: int) int

Send a PPS request to change the communication speed parameters Fi and Di (as specified in ISO-7816-3). PPS0 and PPS1 are sent. PPS2 is ignored. This method waits for the response of the card and then automatically changes the ETU from the Fi and Di values. Scaffold hardware does not support all possible parameters: ETU = Fi/Di must not have a fractional part.

Parameters:

pps1 – Value of the PPS1 byte.

Returns:

New etu value.

Raises:
  • ValueError – if Fi or Di parameters in PPS1 are reserved.

  • ValueError – if target ETU has a fractional part.

  • RuntimeError – if response to PPS request is invalid.

receive(n: int) bytes

Use the ISO-7816 peripheral to receive bytes from the smartcard, and apply direct or inverse convention depending on what has been read in the ATR.

Parameters:

n – Number of bytes to be read.

receive_block() bytes

Receive a T=1 protocol block.

Raises:

T1RedundancyCodeError – If LRC or CRC is wrong.

reset() bytes

Reset the smartcard and retrieve the ATR.

If the ATR is retrieved successfully, the attributes atr convention and protocols are updated.

protocols indicates what protocols are supported. It will

contain 0 if T=0 is supported, and 1 if T=1 is supported.

If only T=1 is supported, exchanges using apdu() will use I-block transmission automatically.

Returns:

ATR from the card.

Raises:

ProtocolError – if the ATR is not valid.

transmit_block(nad: int, pcb: int, info: bytes = b'', trigger: bool = False)

Transmit a T=1 protocol block. Error detection code is calculated and appended automatically.

Parameters:
  • nad – Node address byte.

  • pcb – Protocol control byte.

  • info – Information field.

  • trigger – If True, raise trigger on last byte transmission.

class scaffold.iso7816.Convention(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Possible ISO-7816 communication convention. This is given by the first byte of the ATR returned by the card.

DIRECT = 59
INVERSE = 63
class scaffold.iso7816.T1RedundancyCode(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)

Possible ISO78-16 possible error detection codes that can be used for T=1 protocol. It is indicated in the first TC byte for T=1 of the ATR.

CRC = 1
LRC = 0
class scaffold.iso7816.ProtocolError(message)

Exception raised when a protocol error between the terminal and the smartcard occurs.

class scaffold.iso7816.NoATRDatabase

Thrown during card information lookup if no ATR database could be loaded

class scaffold.iso7816.T1RedundancyCodeError

Thrown when the redundancy code of a received block is invalid.