Commit Graph

382 Commits

Author SHA1 Message Date
Philipp Maier ac34dcc149 pySim-shell: fix and improve file system exporter
The file system exporter function export() selects the exported EF from
inside a try block. It also selects the parent DF again when leaving the
try block. If an exception ocurrs during select this is fine, but if it
happens during read it leaves the EF selected which makes messes up the
recursive filesystem walk.

There are also minor inconsistancies with the exception strings and the
path displayed in the execption strings

Related: OS#4963
Change-Id: Ie9b1712b37e5b39e9016497185510a2a45c4ca6c
2021-04-02 16:32:53 +02:00
Philipp Maier b152a9e0ed pySim-shell: prevent inconsitancy when walking through the FS tree
When using the method walk() to walk through the filesystem tree, then
the action() callback must not change the currently selected file.
Unfortunately this can easily happen and result in unpredictable
behavior. Lets add a check + an exeception for this to make debugging
easier.

Change-Id: I6778faa87bdf5552da74659206bf7a6fc0348d0c
Related: OS#4963
2021-04-02 16:32:53 +02:00
Philipp Maier 46f09af11d pySim-shell: complete CHV/PIN management tools
At the moment we only have a basic version of a verify_chv commnad, but
in order to handle any CHV/PIN related situation we also need commands
to enable, disable, change and unblock CHV.

- fix verify_chv commnad: more distinct parameter names, better help
  strings, correct pin code encoding and add external source lookup
- Add unblock_chv, change_chv, enable_chv and disable_chv commands
- add/fix related functions in commands.py

Change-Id: Ic89446e6bd2021095e579fb6b20458df48ba6413
Related: OS#4963
2021-04-02 16:32:53 +02:00
Philipp Maier b63766b96b pySim-shell: be more specific when finding no ADM-PIN
When no ADM pin is found in the external data source, then print an
error message that tells the user that this is the case.

Change-Id: If8f88b43f283fbe459be1b30db35d984022840ac
Related: OS#4963
2021-04-02 16:21:14 +02:00
Philipp Maier 38c74f6d41 commands: conserve write cycles
When a record or a binary file is written the card goes throth a full
flash/eeprom write cycle at this location, even when the data does not
change. This can be optimized by reading before writing in order to
compere if the data we are about to write is actually different.

Change-Id: Ifd1b80d3ede15a7caa29077a37ac7cf58c9053f1
Related: OS#4963
2021-04-02 16:21:14 +02:00
Philipp Maier 2b11c32e20 pySim-shell: automatic ADM pin from CSV-File
It can be hard to manage ADM pins when working with different cards at
the same time. To make this easier, add an automatic way to determine
the ADM pin for each card from a CSV file.

- add a CardData clas model that can be extended to to get the data from
  various different sources. For now use CSV-Files. Also add a way how
  multiple CardData classes can be registered so that one global get
  function can query all registered CardData classes at once.

- automatically check for CSV-File in home directory and use it as
  default CardData source unless the user specifies a CSV file via
  commandline argument.

- extend the verify_adm command so that it automatically queries the
  ADM pin if no argument is given. Also do not try to authenticate if
  no ADM pin could be determined.

Change-Id: I51835ccb16bcbce35e7f3765e8927a4451509e77
Related: OS#4963
2021-04-02 16:21:14 +02:00
Philipp Maier cba6dbce9a fileystem: fix ADF selection
When the ADF is selected, then this is done by the AID. At the moment
only the first 7 bytes of the AID are used to select the ADF.
sysmo-isim-sja2 tolerates this, but sysmo-usim-sjs1 does not. The Cards
class already has methods to deal with this problem. The method
select_adf_by_aid takes an ADF name and completes the AID from an
internal list. This can be extended to support partial hexadecimal AIDs
as well.

Change-Id: If99b143ae5ff42a889c52e8023084692e709e1b1
Related: OS#4963
2021-04-02 16:21:14 +02:00
Philipp Maier ad073e834a ts_31_102: do not add empty ShellCommands class.
The class ShellCommands defined in ADF_USIM overloads useful CommandSet
classes defined in the superclass, making their commands inaccessible.
Also ts_31_102 does not have such a class definition in the ADF_ISIM
class, so lets remove this class.

Change-Id: I0e67c570fc4f17641d990a9cd239632ecf622de3
Related: OS#4963
2021-04-02 16:21:14 +02:00
Philipp Maier 63f572df42 filesystem: allow selection of arbitrary files
Some cards may have additional propritary EF files which pySim-shell
does not support. If the user knows the exact FID the file can still be
selected and it is possible to read the file type and memory model from
the select response. This info can be used to create a new file object
at runtime that will work like any other EF/DF.

Change-Id: Iafff97443130f8bb8c5bc68f51d2fe1d93fff07c
Related: OS#4963
2021-04-02 16:21:11 +02:00
Merlin Chlosta 05ca36b3f3 Add decoder/encoder for EF.SUCI_Calc_Info
Change-Id: I848a766e6d00be497c7db905475e0681cce197ac
2021-04-02 14:10:10 +02:00
Philipp Maier dd2091a3e0 ts_102_221: use keywords to avoid conflicts with positional args
The Change I83d718ff9c3ff6aef47930f38d7f50424f9b880f removes the
keyword arguments from the CardProfile class constructor. This requires
us to use the keywords during instantiation since we can not rely on
the position anymore.

Change-Id: Ia62597c59287848662dbbedcc38ba90f183c4aca
2021-03-31 17:33:04 +02:00
Philipp Maier 228c98e4c6 pySim-shell: use -a / -A commandline option to authenticate
pySim-shell defines, just like the other pySim programs commandline
arguments that take an ADM pin to authenticate at the card as admin. The
arguments are defined, but not used. Add the missing authentication
part.

Change-Id: I6bed14eb8f4124e28d593cf0816dbe58e7271322
Related: OS#4963
2021-03-30 11:58:39 +02:00
Philipp Maier e6bc4f9032 filesystem: avoid outputting empty lines when there is no data
The do_update_... functions do always print the returned data. However,
there may be no data. If this is the case than an empty line is printed.
This may cause ugly log output, especially when working with scripts.

Change-Id: Ia9715d46ec957544cfbeea98d2fe15eb74f5b884
Related: OS#4963
2021-03-30 11:58:39 +02:00
Philipp Maier 2558aa6999 pySim-shell: add command to show file description
All all files (CardFile) have a human readable description but there is
no command to display that description yet

Change-Id: If716cf3c6b09d53dca652b588671487d5343cf58
Related: OS#4963
2021-03-27 18:37:39 +00:00
Vadim Yanitskiy 98f872bed1 pySim/filesystem: fix mutable default list/dict arguments
Having lists and dictionaries as default argument values is a bad
idea, because the same instance of list/dict will be used by all
objects instantiated using such constructor:

  def appendItem(itemName, itemList=[]):
      itemList.append(itemName)
      return itemList

  print(appendItem('notebook'))
  print(appendItem('pencil'))
  print(appendItem('eraser'))

Output:

  ['notebook']
  ['notebook', 'pencil']
  ['notebook', 'pencil', 'eraser']

Change-Id: I83d718ff9c3ff6aef47930f38d7f50424f9b880f
2021-03-27 18:28:43 +00:00
Philipp Maier 24f7bd3ab5 pySim-shell: add filesystem exporter
add a new command "export" that can either export indidividual files or
a whole directory tree. The command will generate a script that contains
update_binary and update_record commands along with the file contents.
This script can later be used to restore multiple files at once.

Change-Id: I82f3ce92cd91a5ed3c4884d62f6b22e9589c8a49
Related: OS#4963
2021-03-26 22:11:40 +01:00
Philipp Maier f62866f4d3 pySim-shell: output currently selected file using select command
When the select command is entered with no parameters it fails with an
exception. Lets just output the currently selected file and exit
instead.

Change-Id: I541bd5ed14f240cd1c2bd63647c830f669d26130
Related: OS#4963
2021-03-26 22:11:40 +01:00
Philipp Maier 681bc7ba72 pySim-shell: add option to execute script on startup
Add a commondline option so that the user can supply pySim-shell with a
script file name. This script then runs automatically on startup. (to
avoid ending up at the shell prompt a quit command at the end can be
used to exit after script execution)

Change-Id: I69f5224087023650340fbfee74668e1850345f54
Related: OS#4963
2021-03-26 22:11:40 +01:00
Philipp Maier 1e896f3d8c pySim-shell: add ADF.ISIM / ADF.USIM dynamically
currently ADF.ISIM and ADF.USIM are always added regardless if there is
a matching application on the card or not. Lets check what applications
are actually installed and add ADF.ISIM and ADF.USIM dynamically.

Change-Id: I42ee23375f98e6322708c1c4db6d65e1425feecd
Related: OS#4963
2021-03-26 22:11:40 +01:00
Philipp Maier eb72fa461d filesystem: fix typo in method call app()->append()
In the method add_application() the method name should be append()
instead of add().

Change-Id: Ic8ad62567968e09786eac86f219b56a3d3200511
Related: OS#4963
2021-03-26 22:05:04 +01:00
Philipp Maier 9c1a4ece3d pysim-shell: select MF on startup to make commands accessible
On the cration of the PysimApp object only the basic commands in
pySim-shell.py are registered, since the MF is only created but not
selected, the file specific commands of the MF are not available. To
make them available, select the MF once on startup before entering the
cmdloop.

Change-Id: Ib63191f44e7c8ae07b0128a9affba40b44957adc
Related: OS#4963
2021-03-23 15:45:22 +01:00
Philipp Maier 78e32f2b36 utils: fix sw_match()
The SW_match function takes a given status word and compares it against
a pattern that may contain wildcards (x or ?). This works by creating a
masked version of the SW using a pattern first (each hex digit is
replaced by a wildcard charafter if the pattern has a wildcard in the
same position). Once this is done, the resulting masked version is
compared at the pattern. However, the current implementation can not
work, since it compares the input SW against the pattern to decide
wihich chrafters should be masked. The input SW never contains wildcard
charafters.

Change-Id: I805ad32160fcfcb8628bf919b64f7eee0fe03c7e
Related: OS#4963
2021-03-23 12:17:23 +00:00
Philipp Maier 05f42ee929 cards: remove unnecessary execptions.
The _scc.veryif_adm() method already does status word checking
internally and also raises an execption should the authentication be
unsuccessful, so we do not have to put an additional status word check +
execition when we use the method from cards.

Change-Id: I785d27e4d49a9cda1a771b56ce5ac9c1f1d1e79a
Related: OS#4963
2021-03-23 11:54:47 +00:00
Philipp Maier a31e9a9a68 commands: better exception string for authentication failures
At the moment we use the send_apdu_checksw() method to send the APDU for
ADM authentication. This method only checks if the command returns with
sw = 9000. If not it raises an exception that the sw is not as expected.
The user may think that this is a problem with thr reader, pcscd or
pySim in the first place and may try multiple times until the card is
permanently locked. A better execption string that also displays the
tries which are left may be helpful.

Change-Id: Icf428831094f8c1045eefaa8cb2b92e6a36b0c13
Related: OS#4963
2021-03-23 11:54:47 +00:00
Philipp Maier 3aec871978 filesystem: be more strict in method add_file()
The file identifier of a file is strictly defined as a two digit
hexadecimal number. Do not allow adding child files that violate this
constraint.

Change-Id: I096907285b742e611d221b03ba067ea2522e7e52
Related: OS#4963
2021-03-22 22:29:49 +01:00
Philipp Maier d51d8b5575 filesystem: drop __main__ from filesystem.py
The __main__ function in filesystem.py seems to be some experimental
testcode from the very beginning of pySim-shell. Lets drop it.

Change-Id: I34f459469dfc45711ad0928c83184d7f99e0f5e3
Related: OS#4963
2021-03-19 17:48:49 +01:00
Philipp Maier 660615800c filesystem: add comment to inform about checks in add_file()
The method add_file of class CardDF does some constraint checking
to the basic file parameters (e.g. fid). Since one might also expect
those checks in the superclass CardFile lets leave a comment to make
the code better understandable.

Change-Id: Iebae28909fe6aade3bd4024112a222819572d735
Related: OS#4963
2021-03-19 17:48:49 +01:00
Philipp Maier e8bc1b42be filesystem: fix exception string (fid != name)
It is better to use the term "fid" instead of "name" when a reserved FID
is detected.

Change-Id: I054f3b3a156f0164c62610cfde1aec2145c20925
Related: OS#4963
2021-03-19 17:47:44 +01:00
Philipp Maier ff9dae2436 pySim-shell: add functionality to walk through the fs recursively
We might add functionality that may require to walk through the entire
filesystem tree to perform an action to all files at once. Lets add a
generic walker that gets a function pointer that can carray out a file
specific action then. Also add another command that just displays the
whole filesystem tree.

Change-Id: If93d24dfb80c83eda39303c936910fa1fa7f48f8
Related: OS#4963
2021-03-18 21:48:30 +01:00
Philipp Maier 5d3e2592f7 pySim-shell: add "dir" command.
pysim-shell does not have a convinient way to list the files available
in one directory. Tab completion currently is the only way to obtain a
list of the available files. Lets add a dir command to print a file
list.

Change-Id: Ic06a60e0a0ec54d9bb26e151453ceb49d69e3df7
Related: OS#4963
2021-03-18 17:19:17 +01:00
Philipp Maier bd8ed2c4db filesystem: fix flag model used with get_selectable_names()
The flags NAMES, FIDS and APPS do not properly distinguish between
applications and normal files. With APPS it is only possible to exclude
or include the selectable applications in a list with NAMES or FIDS, but
it is not possible to get only the application names or identifiers.

- remove the APPS flag
- rename NAMES to FNAMES and make it only normal file related
- add ANAMES and relate it only to application (ADF) names
- add AIDS and relate it only to application identifiers

Change-Id: Id07e0dcbab10cd78c1b78d37319b7b0e5e83b64d
Related: OS#4963
2021-03-18 17:18:13 +01:00
Philipp Maier 4155573617 filesystem: allow dumping multiple records of a file
At the moment we can only request pySim-shell to dump a specific record
of a file. However, it may be useful to dump multiple records of a
record oriented file at once.

Change-Id: Id62db2cba4e3dfb6a7b3e6be8b892c16d11a8e3e
Related: OS#4963
2021-03-18 15:18:36 +01:00
Vadim Yanitskiy b0f24337b7 Check in requirements.txt to simplify installing dependencies
Change-Id: I88db5e8a661fb3ddc72b7d423a878c0143353d3e
2021-03-12 15:45:44 +01:00
Vadim Yanitskiy 080cc9f794 README.md: add notes about the new 'cmd2' dependency
Change-Id: I314317ab547bc32497839fe70e7a6f6b66bcc8ef
2021-03-12 15:41:01 +01:00
Philipp Maier 7744b6e9d1 filesystem: be case insensitive when selecting files by fid (HEX)
The file identifier (and allso application ids for ADFs), are
hexadecimal. We should be case insensitive when accepting hex
identifiers but file names should still be full matched.

Change-Id: Ibe283a108ddc9058af77c823b7222db555e1e0f6
Related: OS#4963
2021-03-12 07:35:37 +00:00
Philipp Maier 47236500fe utils: add is_hex function to check hex strings
since we have added pySim-shell.py that has a lot of locations where the
user can enter hexadecimal data there is an increased need for input
validation. Lets add a central is_hex function that verifies hex
strings.

Change-Id: Ia29a13c9215357dd2adf141f2ef222c823f8456d
Related: OS#4963
2021-03-12 07:35:37 +00:00
Philipp Maier 786f781a5f filesystem: add flags to filter selectables
When requesting what DF/EF/ADF are selectable it is useful to have some
control of what we do not want in the resulting list.

Change-Id: Idb50a512bfdbfdf2e98f2ce0e89928cb0ff19f5e
Related: OS#4963
2021-03-12 07:35:37 +00:00
Vadim Yanitskiy 3b51f436a4 pySim/exceptions.py: fix referencing an instance member
Change-Id: I6debfc03e9847b907f959e681234daf21df41656
2021-03-12 07:32:17 +00:00
Vadim Yanitskiy d61da8a64c contrib/jenkins.sh: enable automatic execution of unit tests
Change-Id: I7b4bb49efd5e6ae284da063b7899e368ea4f1e22
Related: I4d4facfabc75187acd5238ff4d0f26022bd58f82
2021-03-12 01:13:15 +01:00
Vadim Yanitskiy 46c49d5256 tests/test_utils.py: update expectations for format_xplmn_w_act()
Change-Id: I520328e3490cc3a333d2daad84e745d115196626
2021-03-12 01:12:11 +01:00
Vadim Yanitskiy c8458e2477 pySim/utils.py: fix 3-digit MNC encoding in enc_plmn()
The bug that was attempted to be fixed in [1] actually was in the
encoding API - pySim.utils.enc_plmn().  According to 3GPP TS 31.102,
which points to TS 24.008, the three-digit (E)HPLMN shall be encoded
as shown below (ASCII-art interpretation):

    0   1   2   3   4   5   6   7
  +---+---+---+---+---+---+---+---+
  |  MCC Digit 2  |  MCC Digit 1  |
  +---+---+---+---+---+---+---+---+
  |  MNC Digit 3  |  MCC Digit 3  |
  +---+---+---+---+---+---+---+---+
  |  MNC Digit 2  |  MNC Digit 1  |
  +---+---+---+---+---+---+---+---+

while pySim.utils.enc_plmn() would produce the following:

    0   1   2   3   4   5   6   7
  +---+---+---+---+---+---+---+---+
  |  MCC Digit 2  |  MCC Digit 1  |
  +---+---+---+---+---+---+---+---+
  |  MNC Digit 1  |  MCC Digit 3  |
  +---+---+---+---+---+---+---+---+
  |  MNC Digit 3  |  MNC Digit 2  |
  +---+---+---+---+---+---+---+---+

Initially the _decoding_ API was correct, but then got changed in
[1] to follow buggy pySim's encoding API.  As a result, a (E)HPLMN
programmed with pySim-prog.py would look correct if verified by
pySim-read.py, but the actual file content would be wrong.

This situation shows that our 'program-read-match' build verification
approach alone is insignificant.  The lack of unit test coverage,
at least for the core parts of the project, makes it possible to have
symmetrical bugs in both encoding and decoding API parts unnoticed.

This problem was found while trying to enable dead unit tests in [3].
Change [1] that introduced a symmetrical bug is reverted in [2].

Change-Id: Ic7612502e1bb0d280133dabbcb5cb146fc6997e5
Related: [1] I799469206f87e930d8888367890babcb8ebe23a9
Related: [2] If6bf5383988ad442e275efc7c5a159327d104879
Related: [3] I4d4facfabc75187acd5238ff4d0f26022bd58f82
2021-03-12 01:00:32 +01:00
Vadim Yanitskiy b271be3dc0 Revert "utils.py: Fix for parsing MNC"
This reverts commit bdf3d3597b, which
broke pySim.utils.dec_mnc_from_plmn().  According to 3GPP TS 31.102,
which points to TS 24.008, the three-digit EHPLMN shall be encoded
as shown below (ASCII-art interpretation):

    0   1   2   3   4   5   6   7
  +---+---+---+---+---+---+---+---+
  |  MCC Digit 2  |  MCC Digit 1  |
  +---+---+---+---+---+---+---+---+
  |  MNC Digit 3  |  MCC Digit 3  |
  +---+---+---+---+---+---+---+---+
  |  MNC Digit 2  |  MNC Digit 1  |
  +---+---+---+---+---+---+---+---+

So the original implementation was correct, and we even had a unit
test for it.  Most likely, the SIM card itself was programmed
incorrectly?

Makes 'testDecMNCfromPLMN_threeDigitMNC' pass again.

Change-Id: If6bf5383988ad442e275efc7c5a159327d104879
2021-03-12 01:00:26 +01:00
Vadim Yanitskiy 4ae7c49076 pySim/utils_test.py: prepare this to be executed on Jenkins
As it turns out, we had this set of unit tests since 2018, but
so far they were not executed during the build verification.

Let's fix this:

  * run unittest in discovery mode for all files in 'tests/' (commented out);
  * rename this file, so it can be automatically detected and executed;
  * properly import the API to be tested.

Currently 2 out of 16 unit tests are failing, so we need to get
them passing first and then uncomment the unittest execution.

Change-Id: I4d4facfabc75187acd5238ff4d0f26022bd58f82
2021-03-11 23:54:15 +01:00
Vadim Yanitskiy 7d57edfe2d pySim/utils_test.py: use proper shebang for this executable
Change-Id: I8ad843643b5a97d41a12f74e2ada49088a54974d
2021-03-11 23:01:55 +01:00
Vadim Yanitskiy 3e58d38bdf Get rid of Python 2 specific compatibility leftovers
Change-Id: I0068caa775d89349db2ad378fad22e89832b8d20
2021-03-11 22:59:21 +01:00
Vadim Yanitskiy 5452d64120 ts_51_011: fix bitmask compositing in EF_xPLMNwAcT.enc_act()
This commit fixes two problems (found by semgrep):

  * "'foo' and 'bar' in list" is incorrect, because it's interpreted
    as "'foo' and ('bar' in list)".  Strings with a non-zero length
    evaluate to True, thus it's True if at least 'bar' is present.

  * Copy-pasted 'E-UTRAN NB-S1' checked two times.

The first condition is redundant, and the whole block can be
re-implemented using two independent 'if' statements.

Change-Id: Iceb66160cfb571db8879d3810c55d252c763d320
2021-03-07 21:52:13 +01:00
Denis 'GNUtoo' Carikli 79f5b6080b Python 2 is deprecated, remove backwards compatibility chunks
pySim has already been migrated to Python 3 in another change [1],
and the build verification has been migrated to Debian 10 with
Python 3.7.  However, there is still some backwards compatibility
code left.  Let's get rid of it.

[1] Ic78da9c03e99f59d142c93394051bbc2751f0205

Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
Tweaked-by: Vadim Yanitskiy <vyanitskiy@sysmocom.de>
Change-Id: I430d173535e0cd5bb895b9dfc9070cbc40cfc8ff
2021-03-07 20:33:46 +01:00
Vadim Yanitskiy 1f8acd9884 transport/pcsc: work around Python 3.5 bug: guard disconnect()
Unfortunately, Debian ships old Python (3.5 vs 3.8) and old pyscard
(1.9.4 vs 1.9.9). Calling PCSCCardConnection.disconnect() from a
destructor causes warnings about ignored exceptions:

  AttributeError: 'NoneType' object has no attribute 'disconnect'
  AttributeError: 'NoneType' object has no attribute 'setChanged'
  AttributeError: 'NoneType' object has no attribute 'SCardDisconnect'
  TypeError: 'NoneType' object is not callable

All these exceptions happen in pyscard's own destructors.

Change-Id: I9c644bc5fe9791b141a30bfc13647d77937a82ee
2021-03-07 19:26:08 +00:00
Harald Welte ab34fa895e pySim/utils.py: Attempt to support pycryptodpme
This should resolve the following error when using with pycryptodome
instead of pycrypto:

TypeError: new() missing 1 required positional argument: 'mode'

Change-Id: Ibd3ca00d62b864909f5e89e0feb350268157a4ca
Related: OS#5060
2021-03-05 20:39:18 +00:00
Harald Welte eab8d2adf7 fix TypeError in derive_milenage_opc()
In 4f6ca43e1f we started to use
the bytearray type as 'b' type, but PyCrypto insists on getting
a bytes type.

This fixes the following Exception:
TypeError: argument 1 must be read-only bytes-like object, not bytearray

Change-Id: If2a727ed417ffd56c0f7d7b4e9f633d67fde5ced
Closes: OS#5060
2021-03-05 20:38:50 +00:00