Commit Graph

635 Commits

Author SHA1 Message Date
Harald Welte 6663218ab8 docs: Fix docstring syntax to avoid warnings
pySim/tlv.py:docstring of pySim.tlv.IE.from_bytes:1: ERROR: Unknown target name: "part".
pySim/tlv.py:docstring of pySim.tlv.IE.to_bytes:1: ERROR: Unknown target name: "part".

Change-Id: I170176910c4519005b9276dbe5854aaaecb58efb
2023-11-02 21:45:54 +00:00
Philipp Maier a24755e066 filesystem: fix method build_select_path_to
The method build_select_path_to chops off the first element of the
current path. This is done to prevent re-selection of the first file in
the current path.

Unfortunately chopping off the first element in the current path does
not work properly in a situation when the current path points to the MF.
This would chop off the first and last element in the list and the for
loop below would run 0 times.

To fix this, let's keep the first element and chop it off from the
resulting path.

Related: OS#5418
Change-Id: Ia521a7ac4c25fd3a2bc8edffdc45ec89ba4b16eb
2023-10-31 17:25:55 +01:00
Philipp Maier 1da8636c0f runtime: cosmetic: fix formatting of comment
Change-Id: I4e949a08c1bfab413b82e958a64404390e58148f
2023-10-31 17:25:51 +01:00
Philipp Maier 4af63dc760 transport: print reader device/number on init
When we initialize the reader, we currently tell only which type of
interface we are using, but we do not print the reader number or the
device path.

Let's extend the messages so that the path is printed. To prevent
problems with integration-tests, let's also add an environment variable
that we can use to detect when pySim runs inside a integration-test.

Related: OS#6210
Change-Id: Ibe296d51885b1ef5f9c9ecaf1d28da52014dcc4b
2023-10-26 15:17:07 +00:00
Harald Welte cbc0bdfaa9 euicc: add some first IoT eUICC commands (GSMA SGP.32)
this is far from being complete, just some basic first commands
to get the certificates and eIM configuration.

Change-Id: Ie05108e635ed9c6de10f0ba431cb1b13893f6be8
2023-10-26 15:16:30 +00:00
Harald Welte 884eb551af euicc: Add get_profiles_info command
Example output:

pySIM-shell (02:MF/ADF.ISD-R)> get_profiles_info
{
    "profile_info_seq": {
        "profile_info": {
            "iccid": "98940462222222222222",
            "isdp_aid": "a0000005591010ffffffff8900001200",
            "profile_state": "enabled",
            "service_provider_name": "foobar",
            "profile_name": "foobar",
            "profile_class": "provisioning"
        }
    }
}

Change-Id: I52d136f99dc0eb29905e7ca0cd0865486d3cf65b
2023-10-26 15:16:30 +00:00
Harald Welte 268a2025db Initial support for eUICC
This just adds basic support for the ISD-R application and its
associated STORE DATA command which is used for the ES10x interfaces
between off-card entities and the on-card ISD-R.

Change-Id: Ieab37b083e25d3f36c20f6e9ed3e4bdfdd14a42a
Closes: OS#5637
2023-10-26 15:16:30 +00:00
Philipp Maier 8c82378bfd transport: move argument parser setup into concrete classes
The argument parser is set up globally for all LinkBase objects in
__init__.py. Since we tend to have only platform independed code in
__init__.py, we should move the argument parser setup into the
specific LinkBase classes.

Related: OS#6210
Change-Id: I22c32aa81ca0588e3314c3ff4546f6e5092c11df
2023-10-24 19:28:34 +00:00
Philipp Maier 3077343739 transport: move init message into concrete classes
In in the module __init__.py we print an init message (which type of
LinkBase class is providing the SimLink). However in __init__.py we tend
to have only platform independed code but the message string can already
be categorized as platform depened. Let's put the init message into the
constructor of the concrete classes of LinkBase.

Related: OS#6210
Change-Id: I0a6dd7deb79a5f3e42b29094a1cf2535075fa430
2023-10-24 19:28:34 +00:00
Harald Welte 10669f2ddf utils: Fix bertlv_encode_tag() for multi-byte tags
We used to support only single-byte tags in bertlv_encode_tag,
let's fix that.  The easy option is to simply call bertlv_parse_tag,
as that already supported multi-byte tags.

Change-Id: If0bd9137883c4c8b01c4dfcbb53cabeee5c1ce2b
2023-10-24 15:10:01 +02:00
Harald Welte 6dd6f3e12c prevent SimCardCommands.select_adf_by_aid bypassing lchan
Now that pySim-shell is aware of logical channels and issues almost
all of its APDUs on the currently selected channel, we must also make
sure that ADF selection by AID (implemented by the CardBase class)
issues the SELECT on the respective logical channel.

Before this patch, SELECT ADF by AID would always be issued on the
primary logical channel (0), irrespective of the currently active
RuntimeLchan.

Change-Id: Idf05c297e6a2e24ca539408b8912e348c0782bb4
Related: OS#6230
2023-10-24 15:10:01 +02:00
Harald Welte 46255121e0 pySim-shell: Create + use per-RuntimeLchan SimCardCommands
This new approach will "fork" separate SimCardCommands instances
for each RuntimeLchan.  Higher-layer code should now always use the
RuntimeLchan.scc rather than the RuntimeState.card._scc in order to
make sure commands use the correct logical channel.

Change-Id: I13e2e871f2afc2460d9fd1cd566de42267c7d389
Related: OS#6230
2023-10-24 15:10:01 +02:00
Harald Welte 3dfab9dede commands.py: Add support for multiple logical channels.
Historically we always only had one instance of SimCardCommands, but
with this patch we can now have multiple instances, one for each lchan.

The SimCardCommands class is aware of the logical channel it runs on
and will patch the CLA byte accordingly.

Change-Id: Ibe5650dedc0f7681acf82018a86f83377ba81d30
Related: OS#6230
2023-10-24 15:10:01 +02:00
Harald Welte 49acc06327 RuntimeState: Add type annotation for 'card' argument
Change-Id: I3c5138a918f7e45aabe3972883714d05ee704877
2023-10-21 21:47:04 +02:00
Harald Welte 7997252267 cards.py: Fix type annotation
The CardBaes 'scc' member refers to a SimCardCommands instance,
not to a LinkBase.

Change-Id: If4c0dfbd8c9a03d1a0bc4129bb3c5d5fa492d4cb
2023-10-21 21:47:04 +02:00
Harald Welte 509ecf84fa Use keyword argument for file description argument
While our base classes (TransparentEF / LinFixedEF) always have the
dsecription as 4th argument after "fid, sfid, name", most of the derived
file-specific classes do not share that same argument order.

As seen in the bug fixed by previous Change-Id I7f32c9fd01094620b68b0e54536ecc6cdbe67903
this can have serious consequences.  Let's avoid using unnamed
(positional) arguments for the description text altogether.

Change-Id: Icfb3fd1bae038c54fa14a91aa9f75219d839968c
2023-10-18 23:32:57 +02:00
Harald Welte 28accc88c3 ts_31_102: Fix initialization of file size
We were using positional arguments when instantiating instances
of classes like EF_5GS3GPPLOCI with non-default names/fids/...

However, we got the argument order wrong and were passing the
description string in the position of the file size, which causes
exceptions like the following from pySim-trace:

Traceback (most recent call last):
  File "/home/laforge/projects/git/pysim/./pySim-trace.py", line 198, in <module>
    tracer.main()
  File "/home/laforge/projects/git/pysim/./pySim-trace.py", line 125, in main
    inst.process(self.rs)
  File "/home/laforge/projects/git/pysim/pySim/apdu/__init__.py", line 259, in process
    self.processed = method(self.lchan)
  File "/home/laforge/projects/git/pysim/pySim/apdu/ts_102_221.py", line 152, in process_on_lchan
    if self.cmd_dict['offset'] != 0 or self.lr < self.file.size[0]:
TypeError: '<' not supported between instances of 'int' and 'str'

Let's use named initializers for any arguments after the usual "fid, sfid, name"
initial arguments.

Change-Id: I7f32c9fd01094620b68b0e54536ecc6cdbe67903
2023-10-18 23:21:46 +02:00
Philipp Maier af4e5bb18c transport: do not catch exceptions in init_reader
We currently catch any exceptions that may occur when the card reader is
initialized. Then we print the exception string or the exception type
when no string is available. However, a failure during the reader
initialization is usually a severe problem, so a traceback would provde
a lot of helpful information to debug the issue. So lets not catch any
exceptions at this level so that we get the full backtrace.

Related: OS#6210
Change-Id: I4c4807576fe63cf71a7d33b243a3f8fea0b7ff23
2023-10-16 14:36:02 +02:00
Philipp Maier 58e89eb15a transport: add return type annotation to method __str__
The abstract class LinkBase has no return type annotation on its
__str__ method.

Related: OS#6210
Change-Id: I26d3d2714708dbe957704b60d17ba2afa325b2c4
2023-10-10 12:06:57 +02:00
Philipp Maier 6bfa8a8533 pySim-shell: print device info in case an exception occurs
When an exception occurs while initializing or handling the card we
print a traceback, but we do not print any info that allows us to
identify the device that was involved when the exception occurred. Let's
include the device path or number in the error message before we print
the traceback.

In order to make it easier to print the device information, let's add a
__str__() method to all of our devices. This method shall return the
device number or path.

Related: OS#6210
Change-Id: I200463e692245da40ea6d5b609bfc0ca02d15bdb
2023-10-10 11:51:08 +02:00
Philipp Maier 37e57e0c45 filesystem: add attribute "leftpad" to class LinFixedEF
In some cases, the specs do not specify an absolute record length.
Instead there may be only a minimum record length specified. The card
vendor may then chose to use larger record length at will. This usually
is no problem since the data is usually written from the left and the
remaining bytes are padded at the end (right side) of the data. However
in some rare cases (EF.MSISDN, see also 3GPP TS 51.011, section 10.5.5)
the data must be written right-aligned towards the physical record
length. This means that the data is padded from the left in this case.

To fix this: Let's add a "leftpad" flag to LinFixedEF, which we set to
true in those corner cases. The code that updates the record in
commands.py must then check this flag and padd the data accordingly.

Change-Id: I241d9fd656f9064a3ebb4e8e01a52b6b030f9923
Related: OS#5714
2023-09-07 14:19:26 +02:00
Philipp Maier 0ac4d3c7dc commands: make method verify_binary and verify_record private
The methods verify_binary and verify_record are only used internally
in class SimCardCommands, they can be both private methods. Also lets
move them above the method that uses them.

Related: OS#5714
Change-Id: I57c9af3d6ff45caa4378c400643b4ae1fa42ecac
2023-09-07 13:23:08 +02:00
Philipp Maier a42ee6f99d cards: get rid of method read_iccid
The method read_iccid in class CardBase should be put back to
legacy/cards.py. The reason for this is that it falls in the same
category like read_imsi, read_ki, etc. We should not use those old
methods in future programs since we have a more modern infrastructure
(lchan) now.

Also pySim-shell.py is the only caller of this method now. It is not
used in any other place.

Related: RT#67094
Change-Id: Ied3ae6fd107992abcc1b5ea3edb0eb4bdcd2f892
2023-08-21 18:36:10 +00:00
Philipp Maier d62182ca43 runtime: make sure applications are always listed in the same order
When we print the profile applications. which are not registered in
EF.DIR, we use python sets to subtract the applications which were part
of EF.DIR and hence already listed. Since we use sets the order may be
arbitrary. This is so far not a problem, since the output is meant to be
read by humans, but as soon as we try to use the output for unit-test
verifications we need a consistent order (sorted)

Related: OS#6094
Change-Id: Ie75613910aaba14c27420c52b6596ab080588273
2023-08-01 15:47:27 +02:00
Alexander Couzens c8facea845 Fix the remaining functions using the broken Card.update_ust() call
Card.update_ust() got replaced by the file operation ust_update().
In addition to Change-Id I7a6a77b872a6f5d8c478ca75dcff8ea067b8203e

Fixes: f8d2e2ba08 ("split pySim/legacy/{cards,utils} from pySim/{cards,utils}")
Change-Id: Ie6405cae37493a2101e5089a8d11766fbfed4518
2023-07-29 06:23:15 +00:00
Alexander Couzens 2dd59edd74 ARA-M: fix encoding of the PkgRefDO when using aram_store_ref_ar_do
The command wasn't used the correct dict to allow the encoders to work.

Related: OS#6121
Change-Id: Ic2bc179b413a6b139e07e3e55b93ff921cb020a9
2023-07-29 06:23:15 +00:00
Alexander Couzens 760e421be5 utils.py: remove superfluous import from itself
b2h() is already available.

Change-Id: Ied513a08cc8b5091dd467106250f1e6b5067c3a8
2023-07-29 06:21:54 +00:00
Alexander Couzens 6c5c3f8b2b Reimplement ust_service_activate and ust_service_deactivate for USIM/EF.UST
Fixes: f8d2e2ba08 ("split pySim/legacy/{cards,utils} from pySim/{cards,utils}")
Change-Id: I7a6a77b872a6f5d8c478ca75dcff8ea067b8203e
2023-07-28 15:34:40 +00:00
Philipp Maier 162ba3af3e pySim-trace: mark card reset in the trace
The trace log currently does not contain any information about card
resets. This makes the trace difficult to follow. Let's use the
CardReset object to display the ATR in the trace.

Related: OS#6094
Change-Id: Ia550a8bd2f45d2ad622cb2ac2a2905397db76bce
2023-07-28 10:14:19 +02:00
Philipp Maier 1f46f07e3c utils: tolerate uninitialized fields in dec_addr_tlv
TLV fields holding an address may still be uninitialized and hence
filled with 0xff bytes. Lets interpret those fields in the same way as
we interpret empty fields.

Related: OS#6094
Change-Id: Idc0a92ea88756266381c8da2ad62de061a8ea7a1
2023-07-28 10:14:19 +02:00
Philipp Maier 791f80a44f construct: add adapter Utf8Adapter to safely interpret utf8 text
Uninitialized Files, File records or fields in a File record or File
usually contain a string of 0xff bytes. This becomes a problem when the
content is normally encoded/decoded as utf8 since by the construct
parser. The parser will throw an expection when it tries to decode the
0xff string as utf8. This is especially a serious problem in pySim-trace
where an execption stops the parser.

Let's fix this by interpreting a string of 0xff as an empty string.

Related: OS#6094
Change-Id: Id114096ccb8b7ff8fcc91e1ef3002526afa09cb7
2023-07-26 17:13:54 +02:00
farhadh fec721fcb1 Fixed `mnc` encoding
According to 3GPP TS 24.008 section 10.5.5.36 PLMN identity of the CN operator

Change-Id: I400435abfa8b67da886fc39c801e1abba39725bf
2023-07-21 11:09:49 +00:00
Philipp Maier 92b9356ed2 runtime: fix lchan deletion in method reset
When we perform a reset while multiple channels are open (this is in
particular the case when parsing real world traces with pySim-trace). To
delete those channels during the reset we iterate over the dictionary
using the keys and delete the channels one by one. However, this must
not be done using the keys as index directly. Python will then throw an
exception: "RuntimeError: dictionary changed size during iteration".

Instead using the keys directly we should cast them into a list and then
using that list for the iteration.

Related: OS#6094
Change-Id: I430ef216cf847ffbde2809f492ee9ed9030343b6
2023-07-21 11:52:10 +02:00
Philipp Maier 7d86fe1d8a apdu/ts_102_221: extract channel number from dict before calling del_lchan
When the method del_lchan is called, closed_channel_nr still contains a dict
that contains the channel number under the key 'logical_channel_number'.
This will lead to an exception. We must extact the channel number from
the dict before we can use it with del_lchan. (See also
created_channel_nr)

Related: OS#6094
Change-Id: I399856bc227f17b66cdb4158a69a35d50ba222a7
2023-07-20 15:50:16 +00:00
Philipp Maier 3175d61eb2 cards: fix swapped PIN mapping number
The constant for _adm_chv_num is swapped. It should be 0x0A, rather than
0xA0

Change-Id: I5680d2deee855ef316a98058e8c8ff8cf4edbbb2
2023-07-20 17:36:04 +02:00
Harald Welte 531894d386 move Runtime{State,Lchan} from pySim.filesystem to new pySim.runtime
Those two are really separate concepts, so let's keep them in separate
source code files.

Change-Id: I9ec54304dd8f4a4cba9487054a8eb8d265c2d340
2023-07-12 22:05:14 +02:00
Harald Welte b77063b9b7 pySim/filesystem.py: remove unused class FileData
Change-Id: I62eb446e4995a532227a45c8cc521f5f80535d93
2023-07-12 22:05:14 +02:00
Harald Welte 2d5959bf47 ts_102_221: Remove CardProfileUICCSIM
This profile has always been a hack/work-around for the situation that
a classic GSM SIM is not a UICC, and we didn't yet have the concept of
CardProfileAddons yet, so there was no way to probe and add something
to an UICC which was not an application with its own AID/ADF.

Since now we have CardProfileAddons (including one for GSM SIM),
and pySim-trace (the other user of CardProfileUICCSIM) has also switched
over to using CardProfileUICC + addons, we can remove this work-around.

Change-Id: I45cec68d72f2003123da4c3f86ed6a5a90988bd8
2023-07-12 22:05:14 +02:00
Harald Welte 323a35043f Introduce concept of CardProfileAddon
We have a strict "one CardProfile per card" rule.  For a modern UICC
without legacy SIM support, that works great, as all applications
have AID and ADF and can hence be enumerated/detected that way.

However, in reality there are mostly UICC that have legacy SIM, GSM-R
or even CDMA support, all of which are not proper UICC applications
for historical reasons.

So instead of having hard-coded hacks in various places, let's introduce
the new concept of a CardProfileAddon.  Every profile can have any
number of those.  When building up the RuntimeState, we iterate over the
CardProfile addons, and probe which of those are actually on the card.
For those discovered, we add their files to the filesystem hierarchy.

Change-Id: I5866590b6d48f85eb889c9b1b8ab27936d2378b9
2023-07-12 22:05:14 +02:00
Harald Welte f9e2df1296 cdma_ruim: Fix unit tests and actually enable them
As pySim.cdma_ruim was not imported by test_files.py, the unit tests
were apparently never executed and hence didn't pass.  Let's fix both
of those problems.

Change-Id: Icdf4621eb68d05a4948ae9efeb81a007d48e1bb7
2023-07-12 22:05:14 +02:00
Harald Welte 659d7c11ca cards: all UICC should use sel_ctrl="0400" and SIM "0000"
Hence move this from the derived classes into the respective base
classes SimCardBase and UiccCardBase

Change-Id: Iad197c2b560c5ea05c54a122144361de5742aafd
2023-07-12 22:05:14 +02:00
Harald Welte 775ab01a2b cards: cosmetic rename, argument name should be scc, not ssc
ssc = SimCardCommands

Change-Id: I9d690a0a5b9b49ea342728a29b7d4ed10ac31e4e
2023-07-12 22:05:14 +02:00
Harald Welte 172c28eba8 cards: All derived of SimCardBase use CLA=A0; all UiccCardBase use CLA=00
Change-Id: Id61b549f68410631529349ee62b08a102f609405
2023-07-12 22:05:14 +02:00
Harald Welte b314b9be34 ts_31_102, ts_31_103: Move legacy-only code to pySim.legacy
Change-Id: Ifebfbbc00ef0d01cafd6f058a32d243d3696e97e
2023-07-12 22:05:14 +02:00
Harald Welte 57ad38e661 create pySim.legacy.ts_51_011.py and move legacy code there
Those old flat dicts indicating FID to string-name mapping have long
been obsoleted by the pySim.filsystem based classes.

Change-Id: I20ceea3fdb02ee70d8c8889c078b2e5a0f17c83b
2023-07-12 22:05:14 +02:00
Harald Welte a3961298ef pySim/cards: Add type annotations
Change-Id: Id5752a64b59097584301c860ebf74d858ed3d240
2023-07-12 22:05:14 +02:00
Harald Welte f8d2e2ba08 split pySim/legacy/{cards,utils} from pySim/{cards,utils}
There are some functions / classes which are only needed by the legacy
tools pySim-{read,prog}, bypassing our modern per-file transcoder
classes.  Let's move this code to the pySim/legacy sub-directory,
rendering pySim.legacy.* module names.

The long-term goal is to get rid of those and have all code use the
modern pySim/filesystem classes for reading/decoding/encoding/writing
any kind of data on cards.

Change-Id: Ia8cf831929730c48f90679a83d69049475cc5077
2023-07-12 22:03:59 +02:00
Harald Welte 263fb0871c pySim/cards: Split legacy classes away from core SIM + UICC
This introduces an internal split between
* the code that is shared between pySim-shell and legacy tools, which is
  now in the new class hierarchy {Card,SimCard,UiccCard}Base
* the code that is only used by legacy tools,
  which is using the old class names inherited from the *Base above

All users still go through the legacy {Sim,Usim,Isim}Card classes, they
will be adjusted in subsequent patches.

Change-Id: Id36140675def5fc44eedce81fc7b09e0adc527e1
2023-07-12 21:35:17 +02:00
Harald Welte 02a7f7441f filesystem: Support selecting MF from MF
This was currently not handled in build_select_path_to(), resulting in
weird exceptions like 'Cannot determine path from MF(3f00) to MF(3f00)'

Change-Id: I41b9f047ee5dc6b91b487f370f011af994aaca04
2023-07-11 17:50:48 +02:00
Harald Welte fdcf3c5702 GlobalPlatform ADF.SD: Add command line reference + error message
The get_data shell command didn't have any interactive help / syntax,
and no meaningful error message in case an unknown data object name
was specified by the user.  Let's fix that.

Change-Id: I09faaf5d45118635cf832c8c513033aede1427e5
2023-07-11 08:54:04 +02:00