Commit Graph

156 Commits

Author SHA1 Message Date
Philipp Maier
caabee4ccb ara_m: use class byte of current lchan
The ara_m commands use APDUs with a fix class byte (0x80). This means
that all ARA-M related features only work in the basic logical channel.
To fix this, let's compute the class byte for the current logical channel
dynamically inside the send_apdu methods of SimCardCommands. This will
fix the problem globally.

Related: OS#6531
Change-Id: Ie3e48678f178a488bfaea6cc2b9a3e18145a8d10
2024-08-28 12:53:14 +02:00
Philipp Maier
8c1a1c5cc5 pySim-shell: prevent opening/closing logical channel 0
The basic logical channel 0 is always present. It cannot be created or
closed. Let's restrict the value range of chan_nr, so that only valid
lchan numbers can be passed.

Related: OS#6531
Change-Id: I4eebd9f15fadd18e1caeb033fda36c59446fcab8
2024-08-26 16:58:10 +02:00
Philipp Maier
d5943934a5 pySim-shell, cosmetic: define positional arguments last
When we define command arguments using the ArgumentParser, we sometimes
define the positional arguments first. However, since positional arguments
usually follow after the optional (--xyz) arguments, we should define the
positional arguments last.

Related: OS#6531
Change-Id: I2412eb6e7dc32ae95a575f31d4489ce210d85ea0
2024-08-26 16:58:10 +02:00
Philipp Maier
d20be98ed1 pySim-shell: fix sourcecode formatting
Change-Id: I7133e93366eaacca5ace301172a08ae84e211c0e
2024-08-26 16:58:10 +02:00
Philipp Maier
1f92031079 pySim-shell: fix CardKeyProvider for chv management commands
The CardKeyProvider support for the commands enable_chv, disable_chv,
verify_chv, change_chv and unblock_chv is broken. The reason for this
is the annotation "type=is_decimal" in the argument parser. This annotation
prevents the usage of string placeholders ("PIN1", "PUK1", etc).

Let's fix this by finding a better solution. We can also replace any
missing PIN/PUK code by checking if it is supplied or not. If not,
we query the CardKeyProvider. This also makes the usage of the *_chv
commands more uniform with the verify_adm command.

Related: OS#6531
Change-Id: I565b56ac608e801c67ca53d337bdec9efa3f3817
2024-08-23 06:51:37 +00:00
Philipp Maier
526fdae6e5 pySim-shell: improve fsdump
In the previous patch we have improved the export command. Since
the implementation of the fsdump command is very similar to the
implementation of the export command we can now apply the same
improvements to the fsdump command as well.

Change-Id: I4d2ef7b383025a5bbf122f18ecd51b7d73aaba14
Related: OS#6092
2024-08-12 12:30:27 +02:00
Philipp Maier
c421645ba6 pySim-shell: improve export and enable exportation of DF and ADF files
Since we now have the ability to provide export methods for all file
types in the file system (this also includes DF and ADF files), we need
to support this at shell command level as well. Let's also renovate the
walk method and the action method that does the actual exporting.

Related: OS#6092
Change-Id: I3ee661dbae5c11fec23911775f352ac13bc2c6e5
2024-08-08 15:42:27 +02:00
Philipp Maier
8597b64ee6 runtime: integrate escape route for applications without ADF support
the select_parent method in RuntimeLchan currently implements a way
to escape from an application that has no filesystem support. However,
this escape route can be integrated directly into the select_file
method. This will give us the benefit that it will work transparently
in all code locations.

(This also means we can get rid of the select_parent method again)

Related: OS#6120
Change-Id: Ie6f37d13af880d24a9c7a8a95cef436b603587c7
2024-08-08 15:37:35 +02:00
Philipp Maier
44d51a7b16 pySim-shell: fix typo
Change-Id: I1bd995ae9eb59a44a48da62a7b0262faa84a4f2b
2024-08-05 15:20:15 +02:00
Harald Welte
08d7c10211 pySim-shell: Support other ADMx values beyond ADM1 from 'verify_adm'
Change-Id: Icce6903c1e449889f8bc5003ccfe6af767a26d44
2024-08-04 12:46:02 +02:00
Harald Welte
fdae0ff90d pySim-shell: Support hexadecimal ADM pin in 'verify_adm'
Change-Id: I4191ed79ebe7869d8411d280a32ac2d4bbc210e3
Closes: OS#6480
2024-08-01 11:38:18 +02:00
Harald Welte
de5de0e9db pySim-shell: add "fsdump" command
This command exports the entire filesystem state as one JSON document,
which can be useful for storing it in a noSQL database, or for doing a
structured diff between different such dumps.

It's similar to "export", but then reasonably different to rectify a
separate command.

Change-Id: Ib179f57bc04d394efe11003ba191dca6098192d3
2024-07-29 10:48:22 +00:00
Philipp Maier
43fc875168 pySim-shell: fix comment formatting
Related: OS#6092
Change-Id: Icea88c061436d26a3240fc666fcc3fe1bd36d2ba
2024-07-27 08:22:57 +00:00
Philipp Maier
dff7bb0687 pySim-shell: clean up method calls in do_switch_channel
The function do_switch_channel method calls methods in RuntimeLchan
that should be private. There is also a code duplication in
RuntimeLchan that should be cleaned up.

Related: OS#6092
Change-Id: Ie5e5f45787abaaf032e1b49f51d447653cf2c996
2024-07-27 08:22:04 +00:00
Philipp Maier
4fefac78b8 pySim-shell: fix reset command
The reset command resets the card using the card object. This unfortunately
leaves the RuntimeState uninformed about the event. However, the RuntimeState
class also has a reset method that resets the card and the RuntimeState. Let's
use this reset method. Also fix this method so that it ensures that the SCP is
also no longer present.

Related: OS#6092
Change-Id: I1ad29c9e7ce7d80bebc92fa173ed7a44ee4c2998
2024-07-27 08:22:04 +00:00
Philipp Maier
7858f591fe pySim-shell: turn "ADF-escape-code" into an lchan method.
When we traverse the file system using the command "export" we will
also select all ADFs but not all ADFs may have UICC file system support.
This makes it impossible to exit those ADFs again. To exit anyway we
select an application with filesystem support first and then the parent
EF we wanted to select originally. This method may not only be useful
when traversing the filesystem, so let's put it into the RuntimeLchan
class and change it a little so that it would also work if the ADF in
question is an a sub DF.

Related: OS#6092
Change-Id: I72de51bc7519fafbcc71d829719a8af35d774342
2024-07-27 08:22:04 +00:00
Philipp Maier
d29bdbc2c8 pySim-shell: move export code into filesystem class model
The code that generates the filesystem export lines for the various
different file structures can be moved into the filesystem class model.

This simplifies the code since we do not need any extra logic to
distinguish between the different file structures.

Related: OS#6092
Change-Id: Icc2ee60cfc4379411744ca1033d79a1ee9cff5a6
2024-07-27 08:22:04 +00:00
Philipp Maier
f26042f92d pySim-shell: fix comment formatting
Related: OS#6092
Change-Id: I101868a6f0220b62977c5e633df2607467cfba91
2024-07-26 06:24:07 +00:00
Harald Welte
1aaf978d9f CardKeyProvider: Implement support for column-based transport key encryption
It's generally a bad idea to keep [card specific] key material lying
around unencrypted in CSV files.  The industry standard solution in the
GSMA is a so-called "transport key", which encrypts the key material.

Let's introduce support for this in the CardKeyProvider (and
specifically, the CardKeyProviderCSV) and allow the user to specify
transport key material as command line options to pySim-shell.

Different transport keys can be used for different key materials, so
allow specification of keys on a CSV-column base.

The higher-level goal is to allow the CSV file not only to store
the ADM keys (like now), but also global platform key material for
establishing SCP towards various security domains in a given card.

Change-Id: I13146a799448d03c681dc868aaa31eb78b7821ff
2024-06-04 23:18:37 +02:00
Harald Welte
e4450afb4e pySim.app: Attempt to retrieve the EID of a SGP.22 / SGP.32 eUICC
... and populate the RuntimeState.identity['EID'] wit it, so other
[future] parts of the system can use it.

Let's also print the EID (if available) from the 'cardinfo' shell
command.

Change-Id: Idc2ea1d9263f39b3dff403e1535a5e6c4e88b26f
2024-05-26 11:01:29 +02:00
Harald Welte
7f6102365c pySim-shell: Migrate PySimApp.iccid to RuntimeState.identity['ICCID']
In the previous patch, we've introduced a new 'identities' dict as part
of the runtime state.  Let's migrate our ICCID storage into it for
consistency.

Change-Id: Ibdcf9a7c4e7e445201640bce33b768bcc4460db1
2024-05-26 11:01:29 +02:00
Harald Welte
f47433863e runtime: Introduce an 'identity' dict for things like ATR, ICCID, EID
This patch introduces the dict, as well as its first use for ATR storage

Change-Id: Ief5ceaf5afe82800e33da233573293527befd2f4
2024-05-26 11:01:29 +02:00
Harald Welte
d6ecf272f5 pySim-shell: Fix regression in 'apdu' command on cards without profile
Cards where no profile was detected don't have a logical channel, and
hence must use the raw APDU at all times.

Change-Id: I08e5d190bdb4e62ee808bfd77584cb3e0b85a8ae
Fixes: Change-Id Id0c364f772c31e11e8dfa21624d8685d253220d0
2024-02-05 17:54:51 +01:00
Harald Welte
321973ad20 pySim-shell: Make 'apdu' command use logical (and secure) channel
The 'apdu' command so far bypassed the logical channel and also
the recently-introduced support for secure channels.  Let's change
that, at least by default.  If somebody wants a raw APDU without
secure / logical channel processing, they may use the --raw option.

Change-Id: Id0c364f772c31e11e8dfa21624d8685d253220d0
2024-02-04 17:43:11 +01:00
Harald Welte
41a7379a4f Introduce GlobalPlatform SCP02 implementation
This implementation of GlobalPlatform SCP02 currently only supports
C-MAC and C-ENC, but no R-MAC or R-ENC yet.

The patch also introduces the notion of having a SCP instance associated
with a SimCardCommands instance.  It also adds the establish_scp0w and
release_scp shell commands to all GlobalPlatform Security Domains.

Change-Id: I56020382b9dfe8ba0f7c1c9f71eb1a9746bc5a27
2024-02-04 17:42:30 +01:00
Harald Welte
eecef54eee commands.py: Wrap the transport send_apdu* methods
Let's not have higher level code directly call the transports send_apdu*
methods.  We do this as a precursor to introducing secure channel
support, where the secure channel driver would add MAC and/or encrypt
APDUs before they are sent to the transport.

Change-Id: I1b870140959aa8241cda2246e74576390123cb2d
2024-02-01 12:06:07 +01:00
Harald Welte
66b337079a pySim-shell: Permit 'reset' command also in unqeuipped stage
If we are not 'equipped' as we could not detect any known applications
on the card, we used to only permit the 'apdu' command. However, we
should also permit the 'reset' command, as it also is something that's
possible with ever card, even of unknown types.

Change-Id: I23199da727973d7095ac18031f49e1e8423aa287
2024-01-16 18:48:52 +00:00
Harald Welte
cd18ed0a82 ts_102_221: Better explain 'selected file invalidated'
Some specs call it 'invalidated', others call it 'deactivated'.  If the
user is unfamiliar with this, the error message about "invalidated"
might not be obvious enough; let's also mention 'deactivated' in the
message and explicitly mention that it needs to be activated before use.

Change-Id: I91488b0e7dc25a8970022b09e575485a4165eefa
2024-01-16 19:04:10 +01:00
Philipp Maier
5482737f31 pySim-shell: don't get trapped in applications without file system
When we traverse the file system, we may also end up selecting
applications (ADF), which do not support an USIM/ISIM like file system.
This will leave us without the ability to select the MF (or any other
file) again. The only way out is to select the ISIM or USIM application
again to get the access to the file system again.

Change-Id: Ia2fdd65f430c07acb1afdaf265d24c6928b654e0
Related: OS#5418
2023-12-07 13:21:07 +00:00
Philipp Maier
1c207a2499 pySim-shell: Do not use self.lchan.scc when sending raw APDUs.
When sending raw APDUs, we access the scc (SimCardCommands) object via
the scc member in the lchan object. Unfortunately self.lchan will not be
populated when the rs (RuntimeState) object is missing. This is in
particular the case when no profile could be detected for the card,
which is a common situation when we boostrap an unprovisioned card.

So let's access the scc object through the card object. This is also
more logical since when we send raw APDUs we work below the level of
logical channels.

Change-Id: I6bbaebe7d7a2013f0ce558ca2da7d58f5e6d991a
Related: OS#6278
2023-11-29 15:24:10 +01:00
Philipp Maier
eb3b0dd379 pySim-shell: refuse to execute a startup script on initialization errors
When there is an error on initialization (e.g. card not present), we
should not continue to execute a startup script that was passed with the
pySim-shell commandline. Instead we should print a message that the
startup script was ignored due to errors.

Related: OS#6271
Change-Id: I61329988e0e9021b5b0ef8e0819fb8e23cabf38b
2023-11-24 12:41:18 +01:00
Harald Welte
8fab463e67 pySim-shell: Move init_card() function to new pySim.app module
The point of this is to move generic code out of pySim-shell.py,
paving the way for more/other executables using the full power of
our class model without having to reinvent the wheel.

Change-Id: Icf557ed3064ef613ed693ce28bd3514a97a938bd
2023-11-09 12:36:47 +00:00
Harald Welte
1c849f8bc2 pySim-shell: Reject any non-decimal PIN values
Don't even send any non-decimal PIN values to the card, but reject
them when parsing the command arguments.

Change-Id: Icec1698851471af7f76f20201dcdcfcd48ddf365
2023-11-03 00:43:17 +01:00
Harald Welte
977c5925a1 pySim-shell: permit string with spaces for 'echo' command
before this patch:

pySIM-shell (00:MF)> echo foo bar baz
usage: echo [-h] string
echo: error: unrecognized arguments: bar baz

after this patch:

pySIM-shell (00:MF)> echo foo bar baz
foo bar baz

Change-Id: I1369bc3aa975865e3a8a574c132e469813a9f6b9
2023-11-03 00:43:17 +01:00
Harald Welte
4e59d89a5d pySim-shell: Validate that argument to 'apdu' command is proper hexstr
Let's not even send anything to the card if it's not an even number
of hexadecimal digits

Change-Id: I58465244101cc1a976e5a17af2aceea1cf9f9b54
2023-11-03 00:43:17 +01:00
Harald Welte
f9ea63ea51 pySim-shell: Improved argument validation for verify_adm argument
Let's make sure we don't even bother to ask the card to verify
anything as ADM1 pin which is not either a sequence of decimal digits
or an even number of hex digits (even number of bytes).

Change-Id: I4a193a3cf63462fad73d145ab1481070ddf767ca
2023-11-03 00:43:17 +01:00
Harald Welte
469db9393f pySim-shell: Use argparser for verify_adm to support --help
Let's add a proper argparser instance for the 'verify_adm' command,
avoiding situations where the user types 'verif_adm --help' and then
--help is interpreted as the PIN value, removing one more attempt from
the failed ADM1 counter.

Let's use that opportunity to improve the documentation of the command.

Change-Id: I3321fae66a11efd00c53b66c7890fce84796e658
2023-11-02 21:46:38 +00:00
Harald Welte
0ba3fd996a pySim-shell: Add copyright statement and link to online manual to banner
This way the users are reminded where they can go to read the manual.

Change-Id: Ie86822e73bccb3c585cecc818d4462d4ca6e43c2
2023-11-02 21:46:13 +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
Harald Welte
237ddb5bb3 pySim-shell: Include current logical channel in prompt
Now that pySim-shell can switch between logical channels, let's state
the currently used logical channel in the prompt.

Change-Id: I45781a6fba205eeb4ac7f58d5cb642b7131bdd88
Related: OS#6230
2023-10-24 15:10:01 +02:00
Harald Welte
20650997e8 pySim-shell: Add 'switch_channel' command
We've already had the 'open_channel' and 'close_channel' commands,
which were sent to (and acknowledged by) the card.  However,
those commands didn't affect the pySim-shell state, i.e. all
communication would still happen through the default channel '0'.

With this patch we introduce a 'switch_channel' command, using which
the user can determine which of the (previously opened) logical channels
shall be used by pySim-shell.

Change-Id: Ia76eb45c4925882ae6866e50b64d9610bd4d546d
Closes: 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
bdf595756e pySim-shell: Create/delete RuntimeLchan objects on open/close of channel
We already have the open channel and close_channel commands in
pySim-shell. They are sent to the card and acknowledged, respectively.

We also already do have code that can track multiple different logical
channels (the rs.lchan array).  However, this is currently only used by
pySim-trace, and not by pySim-shell.  Let's change that.

Change-Id: Idacee2dc57e8afe85c79bc85b259064e7f5b83a2
Related: OS#6230
2023-10-21 21:47:04 +02:00
Philipp Maier
7c0cd0a93b pySim-shell: do not fail when EF.ICCID does not exist
An eUICC that has no active eSIM profile does not have an ICCID. (The
reason for this is that EF.ICCID is part of the eSIM profile).
Unfortunately pySim-shell insists on reading the ICCID from EF.ICCID on
startup in order to use it as a lookup key for verify_adm later.

To solve the problem, let's add a try/except block around the section
where EF.ICCID is read. In case of failure we set the ICCID to None,

Related: OS#5636
Change-Id: I8d18c5073946c5a6bb1f93be0ce692a599f46f8c
2023-10-20 20:51:24 +00: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
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
8e03f2f2ed pySim-shell: do not pass failed card object to PysimApp
When the try block in which we also call init_card() fails, there may be
no card object, so we must not pass the card object to PysimApp in the
except block. This is also no problem, PysimApp will run without the
card object until the user executes do_equip for a second attempt.

Related: OS#6210
Change-Id: I28195f442ce007f05f7610c882bbc4a6520a8ce6
2023-10-10 11:26:56 +02:00
Philipp Maier
91c971bf82 pySim-prog, pySim-shell do not use global variables
When __main__ runs different variables get assigned. In particular opts,
scc, sl and ch. Those variables are available in any scope and
technically it is possible to access them. However, lets not do this
since it leads to confusion. Also, pylint will complain about those code
locations.

In pySim-shell.py
- Let's use the proper locations (sl and ch are stored in PysimApp.
- Scc can be assigned in init_card.
- In method walk, the use of the variable opts to call ection_df is wrong,
  lets use **kwargs (see also usage of action_ef).
- The constructor of Cmd2ApduTracer has a parameter cmd2_app, but usese
  the global variable app. Let's use cmd2_app instead.

In pySim-prog.py
- Do not use opts.num in find_row_in_csv_file, use num instead.
- Pass scc to process_card as parameter so that it won't access scc
  in the global scope.

Change-Id: I7f09e9a6a6bfc658de75e86f7383ce73726f6666
Related: OS#6210
2023-10-09 12:37:47 +02:00
Philipp Maier
4840d4dc8f pySim-shell: fix commandline option -a (verify_adm)
The commandline option -a, which does an ADM verification on startup,
does no longer work since the verify_adm method is no longer available
in the card base classes (cards.py). Let's use the verify_chv method
from SimCardCommands instead.

Related: RT#68294
Change-Id: Ic1e54d0e9e722d64b3fbeb044134044d47946f7c
2023-09-06 14:57:55 +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