* don't enter a state we are already in
* enable the UART receiver not only when waiting for CLA, but also
generally when we're waiting for more data from the reader
When the USB host software sets this flag, we terminate the
TPDU transmission after the last character in this frame and
transition again to the WAIT_TPDU state.
I couldn't help but to spend my sunday on working towards card
emulation, including
* various state machines in the target about ISO7816 states
* tc_etu timer import from simtrace1
* req_ctx import from simtrace1 (needs renaming and simplifiation)
* USB protocol description as cardemu_prot.h
* some host-based testing code to test the state machines
The code seems to work fine throughout card reset, sending ATR and
receiving the TPDU header of the first APDU, up to the point where it
marks the TPDU header as to-be-transmitted over th bulk-in endpoint.
Sending the ATR must be done inside the firmware for timing
requirements.
From that point onwards, the host needs to respond at the very least
with a procedure byte, and some indication whether or not the card
emulator should continue to transmit data (card->reader), or receive
data (reader->card).
The code is intentionally not hooked up yet with the USB logic nor with
the UART. I want host-based testing completed before doing that.
we shouldn't re-use the vendor/device ID usd by simtrace1, as the
protocol is incompatible and applications for simtrace 1 don't work with
simtrace2. Also, there's a different processor architecutre in the
hardware.
The host got stuck sometimes when large data frames had to be send
from the host program to SIMtrace. The printouts would just stop
if many large packets were received from the SIM card and needed
to be transferred to the mobile phone.
Increasing the buffer length removed the problem.
When the timeout was too small, the main function would infinitely
loop around, restarting the board and waiting for the USB interface
to get configured. But since configuration seems to take more than
one second, it rarely succeeded.
Increasing the timeout makes the USB configuration finish in the
first try.
Moved the replace function from mitm.py to replace.py.
This implementation is context insensitive for now. It would be
better, to have a mitm class or to pass state information to the
function. Because how else can the MITM code know, whether it gets
passed data to or from the sim card, to or from the phone?
There are more instruction codes, after which data is expected
from the SIM card. Therefore, the array with commands known to
expect SIM card data has been extended. Feel free to extend it
even further.
!! ATTENTION !!
The only synchronization mechanism for parsing APDUs
(naively looking for a 0xA0 byte) is deactivated! It only worked
well for the sniffing mode, but getting out of sync is fatal for
the MITM mode.
!! A NEW MEANS OF SYNCHRONISATION HAS TO BE FOUND !!
When the command a0 c0 00 00 16 was send, and the the bytes
a0 c0 00 00 where read first, and then only the byte 16 was read
from simtrace, the code never entered the if condition if cmd is not
None, and therefore never executed send_receive_cmd.
Bug fix: Check for state APDU_S_SEND_DATA after apdu_split (parsing)
the ACK-instruction byte, in case it was an instruction which requires
an answer from the SIM card.
SCardTransmit expects the last function parameter cmd (the bytes
to be send) to be of type list, but we pass a binary array to
send_receive_cmd.
Therefore, the cmd array has to be converted using its function
tolist().
The code was used as early debug code to read different files from
the SIM card and therefore acquire the IMSI, and other SIM card
specific information.
This only was useful for testing that the firmware worked properly.
Is is not needed for regular use cases.
The commands "cmd1", "cmd2", "cmd_poweron", "cmd_poweroff",
"cmd_get_slot_stat", "cmd_get_param" where early test commands,
but have not been used as such in moths.
A programmer, who wants to send commands to the smartcard, should
use the functions of ccid_raw.py (e.g. send_receive_cmd) instead.
With the python module scapy the headers of each layer have to be created
by hand. Furthermore, in order to use it, the program would have to be
started as root.
Using sockets would be the better. The reason for using scapy was, that
it was the first best thing that I found when searching for python
socket communication.
The next step would be to open and close the socket only once instead
of every time an APDU is send to wireshark.
Furthermore, the ATR probably has to be treated differently from APDU packets.
The data type of incoming and outgoing data should be the same
at all points of the program to make it consistent.
For this program the data type is array.array.