The implementation of the methods select and select_file of class
RuntimeLchan is a bit complex. We access the card directly in several
places which makes it difficult to track the state changes. We should
clean this up so that we call self.rs.card.select_adf_by_aid/
self.scc.select_file from a single place only.
This means that the method select uses the method select_file. This
results in a much cleaner implementation. We also should take care
that the important states that we track (selected_file, selected_adf,
etc.) are updated by a single private method. Since the update always
must happen after a select _select_post is a good place to do this.
Related: OS#5418
Change-Id: I9ae213f3b078983f3e6d4c11db38fdbe504c84f2
The method build_select_path_to uses the internal file system tree model
to find the path to a given file. This works the same for applications
(ADF) as it works for normal files (EF/DF). However, an application can
be selected anytime from any location in the filesystem tree. There is
no need to select a specific path leading to that application first.
This means that if there is an ADF somewhere in the resulting
inter_path, we may clip everything before that ADF.
Related: OS#5418
Change-Id: I838a99bb47afc73b4274baecb04fff31abf7b2e2
We use a trick to probe a file (that does not exist in the local file
model yet). Let's explain further how that works, in particular why we
do not have to upate any state if probing fails.
Change-Id: I2a8af73654251d105af8de1c17da53dfa10dc669
Related: OS#5418
The metaclass uese the 'nested' attribute, while the existing code
accidentially used the 'children' attribute. The latter is used
by instances for actual child classes, while the Class/nested
attribute is for the list of classes whose instancse could be potential
children.
Change-Id: I968bd84d074dcdcec37d99be5d3d4edac9c35a0c
The length value "of course" is a hex value, don't use %02u but %02x
This fixes any eUICC command with a Lc > 10 bytes.
Change-Id: I1e1efbfb9916fc43699602cc889cf4b3d42736f2
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
The encoding was missing a "CHOICE" container and missed the
fact that the refreshFlag presence is mandatory for enable+disable.
Change-Id: I12e2b16b2c1b4b01dfad0d1fb485399827f25ddc
If a TLV was elementary (no nested IEs), and it had only a single
integer content whose value is 0, we erroneously encoded that as
zero-length TLV (len=0, no value part):
>>> rf = pySim.euicc.RefreshFlag(decoded=0);
>>> rf.to_bytes()
b''
>>> rf.to_tlv()
b'\x81\x00'
After this change it is correct:
>>> rf = pySim.euicc.RefreshFlag(decoded=0);
>>> rf.to_bytes()
b'\x00'
>>> rf.to_tlv()
b'\x81\x01\x00'
Change-Id: I5f4c0555cff7df9ccfc4a56da12766d1bf89122f
One of the most important properties of the RuntimeLchan are the
selected_file/adf properties. Let's reformat the code so that those
properties are more pronounced.
Change-Id: I4aa028f66879b7d6c2a1cd102cda8d8ca5ff48b1
Related: OS#5418
When we are in the constructor of RuntimeState, we may/must access the
card object directly. Let's explain why, since it may not be immediately
obvious.
Change-Id: I01f74d5f021d46679d1c9fa83fb8753382b0f88f
Related: OS#5418
The constructor of the RuntimeState object selects the MF befor it does
some other steps. However it does this through the _scc object of the
card object. This method is before we had lchan abstraction, so we
should now use the lchan object like in all other places.
Related: OS#5418
Change-Id: I9a751c0228c77077e3fabb50a9a68e4489e7151c
If we have a list of dicts, and we flatten that into a dict: Only
do that if there are no dicts with duplocate key values in the list,
as otherwise we will loose information during the transformation.
Change-Id: I7f6d03bf323a153f3172853a3ef171cbec8aece7
Closes: OS#6288
Ever since commit 30de9fd8ab in July
we are (properly) using snake_case names in the from_dict (to become
bijective with to_dict). This code was not updated by accident,
creating an exception when using the `aram_get_config`
Change-Id: If216b56b38ab17d13896074aa726278b9ba16923
Related: OS#6119
An ADF may or may not support a file system. For example ADF.ARA-M does
not have any filesystem support, which means the SELECT we may use from
this ADF is limited and an can only select a different application. To
know about this in advance let's add a flag that we set when we
instantiate an ADF.
Change-Id: Ifd0f7c34164685ea18d8a746394e55416fa0aa66
Related: OS#5418
So far we implemented only one round of "Send the APDU, get SW=61xx,
call GET RESPONSE". This permitted us to receive only data up to 256
bytes.
Let's extend that to doing multiple rounds, concatenating the result.
This allows us to obtain arbitrary-length data from the card.
See Annex C.1 of ETSI TS 102 221 for examples showing multiple 61xx
iterations.
Change-Id: Ib17da655aa0b0eb203c29dc92690c81bd1300778
Closes: OS#6287
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
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
The function init_card catches all exceptions and then returns None
objects for card or rs in case of an error. This does not fit in the
style we pursue in pySim. This is in particular true for library
functions. We want those functions to raise exceptions when something is
wrong, so that we can catch the exception at top level. Let's fix this
for init_card now.
Related: OS#6271
Change-Id: I581125d8273ef024f6dbf3a5db6116be15c5c95d
The class property selected_adf is not updated in all locations where an
ADF is selected, this means that we may loose track of the currently
selected ADF in some locations
Change-Id: I4cc0c58ff887422b4f3954d35c8380ddc00baa1d
Related: OS#5418
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
It's better for the human reader (and more obvious that it's a boolean
value) if we decode single Bits as True/False instead of 1/0.
Change-Id: Ib025f9c4551af7cf57090a0678ab0f66a6684fa4
This increases test coverage and also shows where we so far only
have decoders but no encoders yet
Change-Id: I7932bab7c81a2314c1b9477f50b82a46f24d074e
Don't even send any non-decimal PIN values to the card, but reject
them when parsing the command arguments.
Change-Id: Icec1698851471af7f76f20201dcdcfcd48ddf365
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
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
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
pySim-shell output has changed over time, so some examples were
showing outdated content. Let's update those.
Change-Id: I4058719c32b61689522e90eba37253e8accb8ba5
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
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
this is far from being complete, just some basic first commands
to get the certificates and eIM configuration.
Change-Id: Ie05108e635ed9c6de10f0ba431cb1b13893f6be8
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
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
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