Commit
308d7cdf7814860670950c59965db7c7d9263680
by Oliver Smith
docs/Makefile: don't forward shrink to sphinx
Adjust the catch-all target at the end of the Makefile that is supposed to route all unknown targets to sphinx, so it doesn't do this for the shrink target. The shrink target has recently been added to Makefile.common.inc in osmo-gsm-manuals, which gets included right above the catch-all target. So it isn't an unknown target, but for some reason the sphinx catch-all runs in addition to the shrink target (runs shrink-pdfs.sh, see output below) and fails. As I did not add the catch-all logic, preserve it but add an exception for the shrink rule.
Commit
1dd5cb540da0b7346482a16698ef8f5d74487fdb
by laforge
fix SimCardCommands.run_gsm(): always use CLA=0xa0
Depending on the card type (SIM or USIM/ISUM), self.cla_byte may be either 0xa0 or 0x00. Sending RUN GSM ALGORITHM with CLA=0x00 fails with SW=6985 (Command not allowed), so let's make sure that we always use CLA=0xa0 regardless of the card type.
It may sometimes be helpful to get a bit of general information about the card. To sort out problems it sometimes helps to get an idea what card type and ICCID pySim-shell has in memory.
Commit
87dd020d5fbcfadb994d5c808868ee6a0d178fe6
by laforge
Add very basic profile for R-UIM (CDMA) cards
R-UIM (CDMA) cards are pretty much like the normal GSM SIM cards and "speak" the same 2G APDU protocol, except that they have their own file hierarchy under MF(3f00)/DF.CDMA(7f25). They also have DF.TELECOM(7f10) and even DF.GSM(7f20) with a limited subset of active EFs. The content of DF.CDMA is specified in 3GPP2 C.S0023-D.
This patch adds a very limited card profile for R-UIM, including auto- detecion and a few EF definitions under DF.CDMA. This may be useful for people willing to explore or backup their R-UIMs. To me this was useful for playing with an R-UIM card from Skylink [1] - a Russian MNO, which provided 450 MHz CDMA coverage until 2016.
pySim-shell: fix compatibility problem with cmd2 >= 2.0.0 (Settable)
In cmd2 relase 2.0.0 the constructor of Settable adds a settable_object parameter, which apparantly was optional at first, but then became mandatory. Older versions must not have the settable_object parameter but versions from 2.0.0 on require it. Let's add a version check so that we stay compatible to cmd2 versions below and above 2.0.0.
See also: https://github.com/python-cmd2/cmd2
Commit 486734e85988d0d0160147b0b44a37759c833e8a Author: Eric Lin <anselor@gmail.com> Date: 2020-08-19 20:01:50
and
Commit 8f981f37eddcccc919329245b85fd44d5975a6a7 Author: Eric Lin <anselor@gmail.com> Date: 2021-03-16 17:25:34
This commit is based on pySim gerrit change: Ifce40410587c85ae932774144b9548b154ee8ad0
pySim-shell: fix compatibility problem with cmd2 >= 2.0.0 (include_ipy)
In version 2.0.0, the use_ipython parameter in the Cmd constructor is renamed to include_ipy. There are still plenty of older cmd2 installations around, so let's work around this using a version check.
See also: https://github.com/python-cmd2/cmd2
Commit: 2397280cad072a27a51f5ec1cc64908039d14bd1 Author: Kevin Van Brunt <kmvanbrunt@gmail.com> Date: 2021-03-26 18:56:33
This commit is based on pySim gerrit changes: Ifce40410587c85ae932774144b9548b154ee8ad0 I19d28276e73e7024f64ed693c3b5e37c1344c687
Commit
e47ea5f2e574491e69d9eb8ab9ee6fe13c7d78d5
by Oliver Smith
Fix pylint errors
In a previous patch the dependency on cmd2 was changed from cmd2==1.5 to cmd2>=1.5. After this was merged, this lead to the docker images getting rebuilt and now having a higher cmd2 version that gets used in the CI checks. So while the patch was in review, pylint was actually running with a lower cmd2 version and was taking different code paths.
Fix for: pySim-shell.py:30:4: E0611: No name 'fg' in module 'cmd2' (no-name-in-module) pySim-shell.py:30:4: E0611: No name 'bg' in module 'cmd2' (no-name-in-module) pySim-shell.py:154:8: E1123: Unexpected keyword argument 'use_ipython' in method call (unexpected-keyword-arg) pySim-shell.py:171:30: E1120: No value for argument 'settable_object' in constructor call (no-value-for-parameter) pySim-shell.py:173:30: E1120: No value for argument 'settable_object' in constructor call (no-value-for-parameter) pySim-shell.py:175:30: E1120: No value for argument 'settable_object' in constructor call (no-value-for-parameter) pySim-shell.py:176:30: E1120: No value for argument 'settable_object' in constructor call (no-value-for-parameter)
Commit
ade366d2a9bc319d5f353f648b9e7f390de80715
by Vadim Yanitskiy
setup.py: add missing packages for pySim-trace.py
pySim-trace.py is broken if pySim is installed using setup.py:
fixeria@DELL:~$ pySim-trace.py Traceback (most recent call last): File "/usr/bin/pySim-trace.py", line 8, in <module> from pySim.apdu import * ModuleNotFoundError: No module named 'pySim.apdu'
Just like the existing commands for UST/IST: Allow the user to activate/deactivate individual services. As EF.SST also contains information about "allocation" of a service, let's have commands for allocation and activation.
Commit
04bd5140fddd9eee4440122d7882663414885094
by laforge
ts_31_102: Fix EF.NIA FID
The FID in ADF.USIM is different from the FID in DF.GSM. So while we can re-use the ts_51_011 EF_NIA class definition, we must pass in a different fid to the constructor.
Commit
2bee70cbac8c2fbff4c8809e125dc4833884e4a3
by laforge
ts_31_102: Add DF.SAIP support
DF.SAIP (SIMalliance Interoperable Profile) is not part of 31.102, but something from the eSIM/eUICC universe of TCA (formerly known as SIMalliance). However, as 3GPP does not specify how/where the card stores the information required for SUCI calculation, the TCA/SIMalliance standard is the only standard there is. Some CardOS start to use this standard even for non-eSIM/eUICC use cases.
Commit
ba6d6ab64f8f7322adc251ec9ed9814f62e6c18d
by laforge
ts_31_102: EF_SUPI_NAI: Decode/Encode GLI+GCI as UTF-8 strings
According to TS 23.003 Section 28.15 and 28.16 both GLI and GCI are NAI as defined in IETF RFC 7542, which in turn specifies they are encoded in UTF-8.
Commit
03650582e0cda9564e48bebd86049349d928d0be
by laforge
SJA5: Proper encode/decode of TUAK data in EF.USIM_AUTH_KEY
Unfortunately, TUAK requires a number of additional (and differently-sized) parameters, so the format of EF.USIM_AUTH_KEY differs significantly depending on TUAK or non-TUAK case.
Commit
219a5f369c82c5ba266e1e828bd0116fca6f714b
by laforge
OTA: Fix padding of AES CMAC
When using AES CMAC for authentication of OTA messages, we must not pad the user data before calling the CMAC function. This is unlike the DES MAC, where padding to the DES block size is mandatory.
This bug was discovered when trying to talk OTA with AES to a sysmoISIM-SJA5. This patch makes the OTA AES interoperate with the card. Also, with this patch the cryptographic results of pySim/ota.py are identical to those of the java code org.opentelecoms.gsm0348.impl.crypto.CipheringManager
Commit
d75fa3f7c90541db51127ddff97ccf6c3f03734e
by laforge
Switch from pycryptodome to pycryptodomex
So for some weird historical reasons, the same python module is available as pycryptodome (Crypto.* namespace) and pycryptodomex (Cryptodome.* namespace). See the following information on the project homepage: https://www.pycryptodome.org/src/installation
To make things extra-weird, Debian choose to package pycryptodomex as python3-pycryptodome (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=886291).
So in order to support both Debian-packaged and differently-installed packages, let's switch to pycryotodomex on all platforms/installers.
Commit
c85ae4188fe868dbb29cfd29baa3e96221ce6c81
by laforge
Fix result parsing of "suspend_uicc"
prior to this patch, the suspend_uicc command would always cause a python exception as a list of integers was returned by decode_duration rather than a single integer (that can be used with %u format string).
Commit
b0e0dce80adb61aa45221a6ac45ba0e258fc4275
by laforge
ts_102221: Add "resume_uicc" command
We've had a "suspend_uicc" command since commit ec95053249bc7f9308ca1f659d8ef6ac97a6e393 in 2021, but didn't yet have the corresponding "resume" pair.
Note that you cannot really execute this in a reasonable way from within pySim, as it is required to power-cycle the card between SUSPEND and RESUME, see TS 102 221 Section 11.1.22.3.2
Commit
f9a5ba5e0f107458d7dfd68ce96a1b6c0d6096ea
by laforge
31.102: Fix EF.Routing_Indicator for odd number of digits
The routing indicator is BCD-encoded but has an arbitrary length of 1, 2, 3 or 4 digits.
In order to support the odd lengths of 1 or 3, we must not pad on the byte level, but on the nibble level. This requires a slight extension of the Rpad() Adapter.
Commit
f422eb18861906fbc544371496d38b4c95dde09f
by laforge
Add ".py" suffix to sphinx-argparse generated docs
This is important to produce the right command syntax when generating command line reference in the user manual. However, we shouldn't add this kludge to the individual programs, but only to the documentation using the :prog: syntax.
Commit
e345e1126d9cdd248592ac0d9e4ed83500b3ca01
by laforge
pySim-shell: fix reset command
The API of the lchan object has changed. It no longer features the reset method used by the pySim-shell reset command. Let's fix this by using the reset method of the card object.
Commit
721ba9b31f341c6d9219bc3cfe4de73da63beacd
by laforge
tests: Add new, data-driven OTA tests
Rather than writing one test class with associated method for each OTA algorithm / test, let's do this in a data-driven way, where new test cases just have to provide test data, while the code iterates over it.
Commit
985ff31efa340ec390f00a772433635ddb341c90
by laforge
work-around what appears to be a pylint bug
smpp.pdu.pdu_types.DataCodingScheme.GSM_MESSAGE_CLASS very much exists, and I can prove that manually in the python shell. So let's assume this is a pylint bug and work around it
pySim/sms.py:72:21: E1101: Instance of 'DataCodingScheme' has no 'GSM_MESSAGE_CLASS' member (no-member)
Commit
579ac3ec0eb122c83260d7509bc4e6d0cb2fe3b3
by laforge
tlv: Fix IE.from_dict() method
The existing IE.from_dict() method *supposedly* accepts a dict as input value, but it actually expects the raw decoded value, unless it is a nested IE. This is inconsistent in various ways, and results in a bug visible at a higher layer, such as files like EF.{DOMAIN,IMPI,IMPU}, which are transparent files containing a single BER-TLV IE.
Decoding such files worked, but re-encoding them did not, due to the fact that we'd pass a dict to the from_dict method, which then gets assigned to self.decoded and further passed along to any later actual encoder function like to_bytes or to_tlv. In that instance, the dict might be handed to a self._construct which has no idea how to process the dict, as it expects the raw decoded value.
Commit
fa9f348180ee3bb98edee38ec0209d3989ebe42e
by laforge
ts_31_103: enable encode tests for files containing single TLV IE
Now that we have fixed OS#6073 in the previous commit, we can enable the so-far disabled encoder tests for EF.{DOMAIN,IMPU,IMPI} and remove associated FIXMEs.
Commit
f4a01472bf1a5cad38c7db1fd46666a8adfa0b96
by laforge
pySim-shell: Support USIM specific methods/commands on unknown UICC
So far, if no known programmable card (like sysmoISIM) has been found, we were using the SimCard base class. However, once we detect an UICC, we should have switched to the UsimCard class, as otherwise the various methods called by USIM/ISIM specific commands don't exist and we get weird 'SimCard' object has no attribute 'update_ust' execptions.
The entire auto-detection and the legacy SimCard / UsimCard classes are showing the legacy of the code base and should probably be re-architected. However, let's fix the apparent bug for now.
Commit
30de9fd8abc9d7c2c541fea7fa4b97c4ca1a54eb
by laforge
TLV_IE_Collection: use snake-style names during from_dict()
The TLV_IE_Collection, just like the individual TLV classes, do use their snake-style names when converting from binary to dict using the to_dict() method. It is inconsistent (and a bug) to expect the CamelCase names during encoding (from_dict). After all, we want the output of to_dict() to be used as input to from_dict().
Commit
2352f2dcdd4782d11a7dac308d29d77864592f39
by laforge
pySim/tlv.py: Fix TLV_IE_Collection from_dict with nested collections
This is all quite complicated. In general, the TLV_IE.to_dict() method obviously is expected to return a dict (with key equal to the snake-case name of the class, value to the decode IE value). This single-entry dict can then be passed back to the from_dict() method to build the binary representation.
However, with a TLV_IE_Collection, any TLV_IE can occur any number of times, so we need an array to represent it (dict would need unique key, which doesn't exist in multiple instances of same TLV IE). Hence, the TLV_IE_Collection.to_dict() method actually returns a list of dicts, rather than a dict itself. Each dict in the list represents one TLV_IE.
When encoding such a TLV_IE_Collection back from the list-of-dicts, we so far didn't handle this special case and tried to de-serialize with a class-name-keyed dict, which doesn't work.
This patch fixes a regression in the aram_store_ref_ar_do pySim-shell command which got introduced in Change-Id I3dd5204510e5c32ef1c4a999258d87cb3f1df8c8
While we're fixing it, add some additional comments to why things are how they are.
Commit
fdcf3c570248a43fd9f773a7189dfbb450a4fe7a
by laforge
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.
Commit
263fb0871c0c8b6b3cb58eaa1ca1779ce1adf6c4
by laforge
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.
Commit
f8d2e2ba089221d39c52593908aa15df4b6e73d5
by laforge
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.
Commit
f9e2df129605033c5ae3e365d87daed547b5b336
by laforge
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.
Commit
323a35043f360080f7e100dbb9f16929f685371d
by laforge
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.
Commit
2d5959bf47d82e8f394a0ccb54a1e1d8e89456fa
by laforge
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.
Commit
38306dfc047c5dabcd4995ce82f1c15099c830de
by laforge
pySim-shell: Add a mode where a pySim-shell cmd can be passed by shell
This adds a new operation mode for pySim-shell, where a single command can be passed to pySim-shell, which then is executed before pySim-shell terminates.
The comman verify_adm 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.
Commit
7d86fe1d8aed6f4aafb0b450b8e28b2e7cc3949e
by laforge
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)
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.
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.
The trace log currently only shows the parsed APDU. However, depending on the problem to investigate it may be required to see the raw APDU string as well. Let's add an option for this.
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.
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.
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)
pySim-shell: check presence of runtime state before accessing it
When the command equip (do_equip) is executed, it accesses self.rs.profile to see if there are any commands that need to be unregistered before moving on with the card initialization.
However, it may be the case that no runtime state exists at this point. This is in particular the case when the card is completely empty and hence no profile is picked and no runtime state exists.
Commit
a42ee6f99d1cb1e8b3f4c58379291224c0ce4309
by laforge
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.
Commit
71a3fb8b3a38cd70946468a072e9fe9895d73927
by laforge
sim-rest-server: do not select ADF.USIM in connect_to_card
When the function connect_to_card is done, it selects ADF.USIM. This might be contraproductive in case someone needs to access files on MF level in one of the REST methods. Instead fo ADF.USIM, let's use MF as a common ground to start from.
At the moment the only existing REST (info, auth) immediately select ADF.USIM after calling connect_to_card already, so there are no further modifications necessary.
The REST megthd info uses deprecated methods to read the ICCID and the IMSI from the card. However, we can replace those methods by selecting the files we are interested in manually and then reading them.
In the last line of the if,elif,else branch, when we print the ApiError object, we pass the variable sw to str() instead passing it to ApiError() like we do it in the lines above. This is not correct and causes strange exceptions.
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.
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.
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.
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.
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.
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.
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.
Commit
28accc88c3fe8f110e31cadd895bb7fc71e0e226
by laforge
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.
Commit
509ecf84fa4d9e7d6806ad200bbfac9d12a01555
by laforge
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.
Commit
7c0cd0a93b87e1ee52ce6bccdb3a2a7ff3ee7be0
by laforge
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,
Commit
bdf595756ec344cad9db619bff578466c338b855
by laforge
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.
Commit
46255121e0fc5a6cffddc24c992e0dd6b24da425
by laforge
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.
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.
Commit
20650997e8f7652957b83116c16df7f3b180f3b4
by laforge
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.
Commit
10669f2ddf40d4f8293018677535b5626af2720b
by laforge
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.
Commit
307734373937f10305a5c10688a77889730f3b54
by laforge
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.
Commit
8c82378bfd74187ece4f4cddb565a9dad3c746ed
by laforge
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.
Commit
268a2025db0e53dc81af7df32f4ed96524d44411
by laforge
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.
Commit
4af63dc760d212b0aab4c628f5083ab9025e0693
by laforge
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.
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.
Commit
469db9393f18dee986cd0635fc969c050288df36
by laforge
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.
Commit
f9ea63ea51ef4a7bdf6a7ef531a3da9d2d53468e
by laforge
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).
Commit
8fab463e67dc3b41cef6f6ef69f3cc0d42016d5c
by laforge
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.
Commit
578cf12e734cbec2daf16b390bedf9bfae002431
by laforge
runtime: fix tracking of selected_adf
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
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.
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.
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.
Commit
a1850aeccca3c6b62d883612d122e4d022bb4b05
by laforge
filesystem: add flag to tell whether an ADF supports an FS or not
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.
Commit
9c3871177303e950600040463d1664758a555d2f
by Neels Hofmeyr
ara_m: Fix encoding of DeviceInterfaceVersionDO
Ever since commit 30de9fd8abc9d7c2c541fea7fa4b97c4ca1a54eb 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`
Commit
880db3735689b7cc0b7bb0b826b8acd4bf02dcc2
by laforge
flatten_dict_lists(): Don't flatten lists with duplicate keys
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.
runtime: do not use the _scc object of the card object to select MF
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.
runtime: explain why we may access the card object directly
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.
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.
Commit
0f7d48ed692c834e3d40e16bec0403cf6f6a8755
by laforge
tlv: Fix encoding of zero-valued TLVs
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):
Commit
5482737f31bdad8ab9688c35d6cda2cc17de6d96
by laforge
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.
Commit
b582c3c7ea1cb46deb074979e48b20d3e7100732
by laforge
euicc: Fix TLV IE definitions for SetNickname{Req,Resp}
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.
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.
filesystem: use sort path when selecting an application
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.
runtime: refactor file selection methods select and select_file
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.
Commit
b3c46135bb87893d504750ceadfb32df2b17cff2
by laforge
bertlv_parse_len: Fix input data is smaller than num length octets
This can happen if there's a file with invalid encoding on the card, such as a tag followed by all-ff. Let's gracefully ignore it and return zero bytes as response.
Commit
301d6ed14a25b828a458654c9a1d8147cfd91a9c
by laforge
isim: Replace legacy imperative address TLV encoder/decoder with construct
We've recently introduced IPv{4,6}Adapter construct classes and can switch to this instead of using the old imperative encoder/decoder functions {enc,dec}_addr_tlv().
Aside from code cleanup, this also means we now support the IPv6 address type in EF.PCSCF.
Commit
c1085950415f40134b6bc6b4370ce497e7aa63bc
by laforge
move {enc,dec}_addr_tlv functions from pySim.util to pySim.legacy.util
In the previous commit we've stopped using those functions from modern pySim-shell code. Hence, the only remaining user is the legacy tools, so we can move the code to the legacy module.
Commit
0f177c1d290202d808c94eb084f45ae6b383da26
by laforge
transport: Pass argparse.Namespace directly into transport classes
It's odd that the individual transport driver specifies their argparse options but then the core transport part evaluates them individually. This means we cannot add new options within a transport.
Let's pass the Namespace instance into the constructor of the specific transport to improve this.
Commit
ad002797e2bffb8b6a39a839429ba0f8e62b9b79
by laforge
transport/pcsc: Allow opening PC/SC readers by a regex of their name
Opening PC/SC readers by index/number is very error-prone as the order is never deterministic in any system with multiple (hot-plugged, USB) readers. Instead, let's offer the alternative of specifying a regular expression to match the reader name (similar to remsim-bankd).
Commit
baec4e9c81d42a42799062ac7595bc74f0b2b5f5
by laforge
transport: Move printing of reader number/name to generic code
Let's avoid copy+pasting print statements everywhere. The instances do already have a __str__ method for the purpose of printing their name in a generic way.
Commit
542dbf67716f5486dba612ab94da07b6a812599f
by laforge
fix encode/decode of xPLMNwAcT
There are some pretty intricate rules about how GSM and E-UTRAN are encoded, let's make sure we fully support both as per 3GPP TS 31.102 Release 17. As part of this, switch to a sorted list of access technologies, in order to have a defined order. This makes comparing in unit tests much easier. However, it also means that we need to sort the set when printing the list of AcT in pySim-read to generate deterministic output.
Commit
caef0df6638277e1b8ff01b314146944e2b5a61e
by laforge
construct/tlv: Pass optional 'context' into construct decoder/encoder
The context is some opaque dictionary that can be used by the constructs; let's allow the caller of parse_construct, from_bytes, from_tlv to specify it.
Also, when decoding a TLV_IE_Collection, pass the decode results of existing siblings via the construct.
Commit
a5eb924f9efdfe2bd74f406a7172fd526877a394
by laforge
filesystem: use pySim.utils.build_construct()
We recently introduced a pySim.utils.build_construct() wrapper around the raw call of the construct.build() method. So far, this wrapper was only used from pySim.tlv, but let's also use it from pySim.filesystem.
Basically, whenever we use parse_construct(), we should use build_construct() as the inverse operation.
Commit
a9b21bdb1f24e3eabcee82950e4a3efdb90b2fa9
by laforge
tlv: Fix from_dict() symmetry
the to_dict() method generates a {class_name: value} dictionary, for both the nested and non-nested case. However, before this patch, the from_dict() method expects a plain list of child IE dicts in the nested case. This is illogical.
Let's make sure from_dict always expectes a {class_name: value} dict for both nested and non-nested situations.
Commit
2a36c1b9213aa01159557d119e46be88466a2964
by laforge
data-driven TLV unit data test support
While we do have the _test_de_encode data driven tests for file definitions, we don't yet have something similar for derived classes of BER_TLV_IE. This means that TLVs used outside of the filesystem context (for example, decoding the SELECT/STATUS response, but also eUICC and other stuff) do not yet have test coverage.
This commit just adds the related test code, but no test data yet.
Commit
dffe7af5789d9a59d6e12c43a449eaf2955f8443
by laforge
Fix enumeration of GlobbalPlatformISDR during card_init()
We used __subclasses__(), but this only returns the immediate subclasses and not all further/nested subclasses. Instead, we must use the pySim.utils.all_subclasses() function to really get all of them.
The hack to use the method signature of the constructor to determine if it's an intermediate class didn't work, as even GlobbalPlatformISDR has a optional argument for non-default AIDs. So let's introduce an explicit class attribute for that purpose.
Commit
842fbdb15d50588bc427e9ed75ad720e578efb38
by laforge
add PlmnAdapter for decoding PLMN bcd-strings like 262f01 to 262-01
The human representation of a PLMN is usually MCC-MNC like 262-01 or 262-001. Let's add a PlmnAdapter for use within construct, so we can properly decode that.
Commit
f6fceb8684c6aaccdf2d0661663866a52bb0cc66
by laforge
Implement convoluted encoding of UCS-2 as per TS 102 221 Annex A
TS 102 221 Annex A defines three variants of encoding UCS-2 characters into byte streams in files on UICC cards: One rather simplistic one, and two variants for optimizing memory utilization on the card.
Let's impelement a construct "Ucs2Adapter" class for this.
Commit
69bdcf50228a947a39cbf0c9b25ec1f21eaaf276
by laforge
Fix TLV_IE_Collection.from_tlv in certain situations
The existing code used to produce an empty output in situations where a TLV_IE_Collection would be parsed from a single TLV only with some additional trailing padding:
>>> from pySim.utils import h2b >>> from pySim.ts_31_102 import EF_CSGT >>> t = EF_CSGT.Csgt_TLV_Collection() >>> t.from_tlv(h2b('8906810300666f6fff')) [TextCsgType(foo)] >>> t.to_dict() []
This was caused by an early return (actually returning the decoded result) but *without updating self.children*.
Commit
ce01f48b0084e067abd7718e207a6f2b85a5471e
by laforge
test_files: Test decoder also with ff-padded input
It's customary in the SIM card universe to right-pad data with ff bytes. So far we only test decoders without such padding, which is unrealistic. Let's also tests the decoders with extra 'ff' padding present.
For some files this doesn't make sense, so we add a _test_no_pad class attribute that can be spcified to prevent this new "test with ff-padding" from being executed for the test data of the class.
Commit
1c0a2491317d8ea82d3d1f3e0314befe46513282
by laforge
commands: Ignore exceptions during READ while UPDATE
If we are reading a file to check if we can skip the write to conserve writes, don't treat exceptions as fatal. The file may well have the access mode in a way that permits us to UPDATE but not to READ. Simply fall-back to unconditional UPDATE in this case.
Commit
e13403b2065f53c648929861132b7b77fef6e6e7
by laforge
ts_31_102: Start to use construct for EF.SUCI_Calc_Info
We cannot fully switch to construct for all of it easily due to the priority value and the ordering/sorting by priority implemented in the hand-coded version. But we can at least migrate the encode/decode of the hnet_pubkey_list via construct.
Commit
b0c9ccba66ebe861a7ff8b18e2f778a0d365670b
by laforge
construct: avoid StreamError exceptions due to files containing all-ff
In smart cards, files/records containing all-ff means they are simply not used/initialized. Let's avoid raising exceptions when interpreting 0xff as length value and reading less bytes as value.
Commit
5b623a124701cd170ea6c25f7769261a346914c2
by laforge
ts_102_310: Add file definitions resembling ETSI TS 102 310 (EAP)
The definitions are not used yet, as one would have to add that dynamically based on which EF.DIR entries contain the 0x73 discretionary template. As I don't have any cards implementing this so far, I'll skip that part.
Commit
d657708df25fb8d29f7091f35bb5809668ff3b91
by laforge
add contrib/unber.py utility
This tool is a replacement for asn1c 'unber' program with a much more useful/readable output: * contains hexadecimal raw tag values * contains hexdump of value, rather than HTML entities in pseudo-XML
Commit
5bbb144a319393e0b2bdd06f403905f28528e459
by laforge
Initial proof-of-concept SM-DP+ for GSMA consumer eSIM RSP
This commit introduces
* the osmo-smdpp.py program implementing the main procedures and the HTTP/REST based ES9+ * python modules for ES8+ and non-volatile RSP Session State storage * the ASN.1 source files required to parse/encode RSP * 3GPP test certificates from SGP.26 * an unsigned profile package (UPP) of a SAIP v2.3 TS48 test profile
As I couldn't get the 'Klein' tls support to work, the SM-DP+ code currently does not support HTTPS/TLS but plan HTTP, so you either have to modify your LPA to use HTTP instead of HTTPS, or put a TLS proxy in front.
I have successfully installed an eSIM profile on a test eUICC that contains certificate/key data within the test CI defined in GSMA SGP.26
Commit
91842b471db50de2d704119cf93b79467654b971
by laforge
Constrain user input to hex-string in argparse
We do have an is_hexstr function which we should use anywhere where we expect the user to input a string of hex digits. This way we validate the input before running in some random exception.
Commit
7ba09f9392c8023842a7b5576936cb21ff85c6c0
by laforge
euicc: Migrate ECASD + ISD-R over to global_platform.CardApplicationSD
Actually, the GSMA eUICC is a kind of derivative of a GlobalPlatform card, and the ECASD and ISD-R are security domains. As such, we should make them derived classes of global_platform.CardApplicationSD which means they inherit some of the shared shell_commands etc.
Commit
1f7a9bd5b40da67d2d8fbccb190d86c50db241d5
by laforge
TLV: Add DGI encoding of "GP Scripting Language Annex B"
The DGI encoding is specified in Annex B of the "GlobalPlatform Systems Scripting Language Specification v1.1.0"
which is an "archived" specification that is no longer published by GlobalPlatform, despite it being referenced from the GlobalPlatform Card Specification v2.3, which is the basis of the GSMA eSIM specifications.
For some reason it was the belief of the specification authors that yet another format of TLV encoding is needed, in addition to the BER-TLV and COMPREHENSION-TLV used by the very same specifications.
The encoding of the tag is not really specified anywhere, but I've only seen 16-bit examples. The encoding of the length is specified and implemented here accordingly.
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.
Commit
66b337079a17aea5105b64cc381103157dcc9a9d
by laforge
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.
Commit
0311c92e961b61b5c4b383558cd8d15408be90d9
by laforge
Fix encoding of decoded/json data in update_{record_binary}_decoded
The patch introducing the is_hexstr type into the argparser was accidentially also introduce in two locations where we actually don't expect a hex-string.
This is a partial revert of I6426ea864bec82be60554dd125961a48d7751904
Commit
18d0a7de96a1f2437d69ce140b8f727fc187ad8e
by laforge
global_platform: Add shell command for PUT KEY
This command is used for installation of GlobalPlatform keys. We only implement the command without secure messaging at this point, as it is used during card personalization. Authentication will later be handled by generic implementations of SCP02 and/or SCP03.
Commit
5e0439f881a8f94671742181dea8012a33f6c1d1
by laforge
ara_m: Permit encoding of empty AID (--aid '') in ARA-M rules
Encoding an empty AID-REF-DO (4F) is neccessary to achieve the meaning described in "Secure Element Access Control - Public Release v1.0" Table 6-1: "Empty: Indicates that the rules to be stored or retrieved are associated with all SE applications not covered by a specific rule".
Commit
7f2263b4a005f8ee50507068ee1192c618e23bc4
by laforge
runtime: Reset selected_file_fcp[_hex] if SELECT returns no data
In case SELECT doesn't return any response data, we must reset the lchan.selected_file_fcp* members to None to prevent pySim-shell preventing stale data from the previously selected file.
Commit
263e3094ba445acf2ad5ee50d31dbca6a7c3ddc5
by laforge
requirements.txt: Switch to osmocom fork of asn1tools
This is sadly required as the Interoperable Profile format must process elements of an ASN.1 sequence in order, which doesn't work if the parser puts the elements in a python dict.
The osmocom fork of asn1tools hence uses OrderedDict to work around this problem.
Commit
3f3fd1a84153c7fa59b7cf75a02aee167dd67a94
by laforge
add SAIP template handling + v3.1 definitions
This adds classes for describing profile templates as well as derived classes defining the profile templates of the "Profile Interoperability Technical Specification", specifically it's "ANNEX A (Normative): File Structure Templates Definition"
We need a machine-readable definition of those templates, so we can fully interpret an unprotected profile package (UPP), as the UPP usually only contains the increment/difference to a given teplate.
Commit
eecef54eee90b2cffc3c73d76648673c4aa3c727
by laforge
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.
Commit
41a7379a4f5995e0ba5e127776e0cb0b189306a5
by laforge
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.
Commit
321973ad202a897faa61f7b35f62f3d9237b928e
by laforge
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.
Commit
a7eaefc8d9a43b28eda248e13abd560191571561
by laforge
global_platform: add set_status command
Using this command, one can change the life cycle status of on-card applications, specifically one can LOCK (disable) them and re-enable them as needed.
Commit
afd89ca36de806efdbc4b62c61fcfe8783a784db
by laforge
Contstrain argparse integers to permitted range
In many casese we used type=int permitting any integer value, positive or negative without a constratint in size. However, in reality often we're constrained to unsigned 8 or 16 bit ranges. Let's use the auto_uint{8,16} functions to enforce this within argparse before we even try to encode something that won't work.
Commit
af8826a02bc85b47e6568b6c7ba42629cf1ef005
by laforge
Implement Global Platform SCP03
This adds an implementation of the GlobalPlatform SCP03 protocol. It has been tested in S8 mode for C-MAC, C-ENC, R-MAC and R-ENC with AES using 128, 192 and 256 bit key lengh. Test vectors generated while talking to a sysmoEUICC1-C2T are included as unit tests.
Commit
7156a40187325259a023312747d4c55ec530747e
by laforge
construct: Add StripTrailerAdapter
In smart cards, we every so often encounter data types that contain a bit-mask whose length depends on whether or not there are any of the least-significant bits are set. So far we worked around this with some kind of Struct('byte1', 'byte2'/COptional, 'byte3'/COptional) approach.
Let's do thisin a generic way using the new StripTrailerAdapter.
pySim/card_key_provider.py:57:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/card_key_provider.py:61:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens)
pySim/card_handler.py:100:0: C0325: Unnecessary parens after '=' keyword (superfluous-parens) pySim/card_handler.py:100:24: C0121: Comparison 'self.cmds.get('verbose') == True' should be 'self.cmds.get('verbose') is True' if checking for the singleton value True, or 'bool(self.cmds.get('verbose'))' if testing for truthiness (singleton-comparison) pySim/card_handler.py:29:0: C0411: standard import "import subprocess" should be placed before "from pySim.transport import LinkBase" (wrong-import-order) pySim/card_handler.py:30:0: C0411: standard import "import sys" should be placed before "from pySim.transport import LinkBase" (wrong-import-order) pySim/card_handler.py:31:0: C0411: third party import "import yaml" should be placed before "from pySim.transport import LinkBase" (wrong-import-order)
Commit
c5c97281273c02a24464fe152915266d47de2920
by laforge
pylint: cards.py
pySim/cards.py:30:0: W0401: Wildcard import pySim.utils (wildcard-import) pySim/cards.py:41:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/cards.py:55:4: R1711: Useless return at end of function or method (useless-return) pySim/cards.py:78:8: R1725: Consider using Python 3 style super() without arguments (super-with-arguments) pySim/cards.py:91:8: R1725: Consider using Python 3 style super() without arguments (super-with-arguments) pySim/cards.py:159:12: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/cards.py:28:0: C0411: standard import "import abc" should be placed before "from pySim.ts_102_221 import EF_DIR" (wrong-import-order) pySim/cards.py:25:0: W0611: Unused Dict imported from typing (unused-import) pySim/cards.py:28:0: W0611: Unused import abc (unused-import)
Commit
8e7d28cad725fd393ff4a16d5c80f684502dea0e
by laforge
pylint: ota.py
pySim/ota.py:21:0: W0401: Wildcard import construct (wildcard-import) pySim/ota.py:129:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/ota.py:150:8: W0107: Unnecessary pass statement (unnecessary-pass) pySim/ota.py:192:8: W0612: Unused variable 'padded_data' (unused-variable) pySim/ota.py:202:8: W0107: Unnecessary pass statement (unnecessary-pass) pySim/ota.py:207:8: W0107: Unnecessary pass statement (unnecessary-pass) pySim/ota.py:210:4: C0103: Method name "fromKeyset" doesn't conform to snake_case naming style (invalid-name) pySim/ota.py:239:8: W0107: Unnecessary pass statement (unnecessary-pass) pySim/ota.py:242:4: C0103: Method name "fromKeyset" doesn't conform to snake_case naming style (invalid-name) pySim/ota.py:328:4: W0221: Number of parameters was 4 in 'OtaDialect.encode_cmd' and is now 5 in overriding 'OtaDialectSms.encode_cmd' method (arguments-differ) pySim/ota.py:392:4: W0221: Number of parameters was 3 in 'OtaDialect.decode_resp' and is now 4 in overriding 'OtaDialectSms.decode_resp' method (arguments-differ)
Commit
e8439d96394ca1d2b4273182968f23d652a6497e
by laforge
pylint: sms.py
pySim/sms.py:23:0: W0404: Reimport 'Flag' (imported line 23) (reimported) pySim/sms.py:54:4: C0103: Method name "fromBytes" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:60:4: C0103: Method name "toBytes" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:120:4: C0103: Method name "fromBytes" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:132:4: C0103: Method name "fromSmpp" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:137:4: C0103: Method name "toSmpp" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:141:4: C0103: Method name "toBytes" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:188:4: C0103: Method name "fromBytes" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:192:8: W0612: Unused variable 'flags' (unused-variable) pySim/sms.py:209:4: C0103: Method name "toBytes" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:228:4: C0103: Method name "fromSmpp" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:236:4: C0103: Method name "fromSmppSubmit" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:279:4: C0103: Method name "fromBytes" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:306:12: W0107: Unnecessary pass statement (unnecessary-pass) pySim/sms.py:311:12: W0107: Unnecessary pass statement (unnecessary-pass) pySim/sms.py:319:4: C0103: Method name "toBytes" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:339:4: C0103: Method name "fromSmpp" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:347:4: C0103: Method name "fromSmppSubmit" doesn't conform to snake_case naming style (invalid-name) pySim/sms.py:373:4: C0103: Method name "toSmpp" doesn't conform to snake_case naming style (invalid-nam
Commit
eb18ed08b075797618fb74d5c748b1d12ead9028
by laforge
pylint: ts_31_102_telecom.py
pySim/ts_31_102_telecom.py:45:0: C0325: Unnecessary parens after '=' keyword (superfluous-parens) pySim/ts_31_102_telecom.py:33:0: W0401: Wildcard import construct (wildcard-import) pySim/ts_31_102_telecom.py:76:15: C0121: Comparison 'in_json[srv]['activated'] == True' should be 'in_json[srv]['activated'] is True' if checking for the singleton value True, or 'in_json[srv]['activated']' if testing for truthiness (singleton-comparison) pySim/ts_31_102_telecom.py:85:23: W0612: Unused variable 'sw' (unused-variable) pySim/ts_31_102_telecom.py:124:22: W0612: Unused variable 'sw' (unused-variable) pySim/ts_31_102_telecom.py:32:0: C0411: third party import "from construct import Optional as COptional" should be placed before "from pySim.tlv import *" (wrong-import-order) pySim/ts_31_102_telecom.py:33:0: C0411: third party import "from construct import *" should be placed before "from pySim.tlv import *" (wrong-import-order)
Commit
fd9188d306365e9063bf83a2ff21c06873fe3a31
by laforge
pylint: cat.py
pySim/cat.py:586:4: W0237: Parameter 'do' has been renamed to 'x' in overriding 'PlmnWactList._from_bytes' method (arguments-renamed) pySim/cat.py:981:8: W0120: Else clause on loop without a break statement, remove the else and de-indent all the code inside it (useless-else-on-loop) pySim/cat.py:1000:4: W0221: Number of parameters was 3 in 'TLV_IE_Collection.from_bytes' and is now 2 in overriding 'ProactiveCommand.from_bytes' method (arguments-differ) pySim/cat.py:1010:12: W0612: Unused variable 'dec' (unused-variable) pySim/cat.py:1010:17: W0612: Unused variable 'remainder' (unused-variable) pySim/cat.py:1022:4: W0221: Number of parameters was 2 in 'TLV_IE_Collection.to_bytes' and is now 1 in overriding 'ProactiveCommand.to_bytes' method (arguments-differ) pySim/cat.py:22:0: C0411: standard import "from typing import List" should be placed before "from bidict import bidict" (wrong-import-order) pySim/cat.py:26:0: C0411: third party import "from construct import Int8ub, Int16ub, Byte, Bytes, Bit, Flag, BitsInteger" should be placed before "from pySim.utils import b2h, h2b, dec_xplmn_w_act" (wrong-import-order) pySim/cat.py:27:0: C0411: third party import "from construct import Struct, Enum, Tell, BitStruct, this, Padding, RepeatUntil" should be placed before "from pySim.utils import b2h, h2b, dec_xplmn_w_act" (wrong-import-order) pySim/cat.py:28:0: C0411: third party import "from construct import GreedyBytes, Switch, GreedyRange, FlagsEnum" should be placed before "from pySim.utils import b2h, h2b, dec_xplmn_w_act" (wrong-import-order) pySim/cat.py:23:0: W0611: Unused h2b imported from pySim.utils (unused-import) pySim/cat.py:26:0: W0611: Unused Bit imported from construct (unused-import) pySim/cat.py:26:0: W0611: Unused Flag imported from construct (unused-import) pySim/cat.py:27:0: W0611: Unused Tell imported from construct (unused-import) pySim/cat.py:27:0: W0611: Unused Padding imported from construct (unused-import) pySim/cat.py:27:0: W0611: Unused RepeatUntil imported from construct (unused-import)
Commit
f5a8e70f44acafc0d46fe573d5780471e04363d8
by laforge
pylint: gsm_r.py
pySim/gsm_r.py:97:0: W0311: Bad indentation. Found 11 spaces, expected 12 (bad-indentation) pySim/gsm_r.py:32:0: C0411: standard import "from struct import pack, unpack" should be placed before "from pySim.utils import *" (wrong-import-order) pySim/gsm_r.py:33:0: C0411: third party import "from construct import Struct, Bytes, Int8ub, Int16ub, Int24ub, Int32ub, FlagsEnum" should be placed before "from pySim.utils import *" (wrong-import-order) pySim/gsm_r.py:34:0: C0411: third party import "from construct import Optional as COptional" should be placed before "from pySim.utils import *" (wrong-import-order) pySim/gsm_r.py:35:0: C0412: Imports from package pySim are not grouped (ungrouped-imports) pySim/gsm_r.py:30:0: W0611: Unused import enum (unused-import) pySim/gsm_r.py:32:0: W0611: Unused pack imported from struct (unused-import) pySim/gsm_r.py:32:0: W0611: Unused unpack imported from struct (unused-import) pySim/gsm_r.py:39:0: W0611: Unused import pySim.ts_51_011 (unused-import)
Commit
181becb676f5a769eb67cd7d05b45d5bdb10e400
by laforge
pylint: transport/modem_atcmd.py
pySim/transport/modem_atcmd.py:70:0: C0325: Unnecessary parens after 'assert' keyword (superfluous-parens) pySim/transport/modem_atcmd.py:28:0: W0401: Wildcard import pySim.exceptions (wildcard-import) pySim/transport/modem_atcmd.py:60:22: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck) pySim/transport/modem_atcmd.py:72:12: W0707: Consider explicitly re-raising using 'except Exception as exc' and 'raise ReaderError('Failed to send AT command: %s' % cmd) from exc' (raise-missing-from) pySim/transport/modem_atcmd.py:120:12: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/transport/modem_atcmd.py:138:8: W1201: Use lazy % formatting in logging functions (logging-not-lazy) pySim/transport/modem_atcmd.py:170:12: W0707: Consider explicitly re-raising using 'except Exception as exc' and 'raise ReaderError('Failed to parse response from modem: %s' % rsp) from exc' (raise-missing-from) pySim/transport/modem_atcmd.py:168:13: W0612: Unused variable 'rsp_pdu_len' (unused-variable) pySim/transport/modem_atcmd.py:21:0: C0411: standard import "import time" should be placed before "import serial" (wrong-import-order) pySim/transport/modem_atcmd.py:22:0: C0411: standard import "import re" should be placed before "import serial" (wrong-import-order) pySim/transport/modem_atcmd.py:23:0: C0411: standard import "import argparse" should be placed before "import serial" (wrong-import-order) pySim/transport/modem_atcmd.py:24:0: C0411: standard import "from typing import Optional" should be placed before "import serial" (wrong-import-order) pySim/transport/modem_atcmd.py:28:0: W0614: Unused import(s) NoCardError and SwMatchError from wildcard import of pySim.exceptions (unused-wildcard-import)
Commit
7781c70c09689d2ccfea11d20931a2eff9da2a5f
by laforge
pylint: transport/pcsc.py
pySim/transport/pcsc.py:26:0: W0404: Reimport 'CardConnectionException' (imported line 26) (reimported) pySim/transport/pcsc.py:60:4: R1711: Useless return at end of function or method (useless-return) pySim/transport/pcsc.py:74:12: W0707: Consider explicitly re-raising using 'except CardRequestTimeoutException as exc' and 'raise NoCardError() from exc' (raise-missing-from) pySim/transport/pcsc.py:86:12: W0707: Consider explicitly re-raising using 'except CardConnectionException as exc' and 'raise ProtocolError() from exc' (raise-missing-from) pySim/transport/pcsc.py:88:12: W0707: Consider explicitly re-raising using 'except NoCardException as exc' and 'raise NoCardError() from exc' (raise-missing-from) pySim/transport/pcsc.py:22:0: W0611: Unused Union imported from typing (unused-import)
Commit
fdaefd9a8a8f0496cce40baeafd5ddd6a66bccca
by laforge
pylint: transport/serial.py
pySim/transport/serial.py:54:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/transport/serial.py:89:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/transport/serial.py:225:0: C0325: Unnecessary parens after 'while' keyword (superfluous-parens) pySim/transport/serial.py:63:12: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/transport/serial.py:106:8: R1720: Unnecessary "elif" after "raise", remove the leading "el" from "elif" (no-else-raise) pySim/transport/serial.py:124:12: W0707: Consider explicitly re-raising using 'except Exception as exc' and 'raise ValueError('Invalid reset pin %s' % self._rst_pin) from exc' (raise-missing-from) pySim/transport/serial.py:204:12: R1723: Unnecessary "elif" after "break", remove the leading "el" from "elif" (no-else-break) pySim/transport/serial.py:20:0: C0411: standard import "import time" should be placed before "import serial" (wrong-import-order) pySim/transport/serial.py:21:0: C0411: standard import "import os" should be placed before "import serial" (wrong-import-order) pySim/transport/serial.py:22:0: C0411: standard import "import argparse" should be placed before "import serial" (wrong-import-order) pySim/transport/serial.py:23:0: C0411: standard import "from typing import Optional" should be placed before "import serial" (wrong-import-order)
Commit
528d9225100724a928b71d2974775adc8754fd89
by laforge
pylint: apdu_source/gsmtap.py
pySim/apdu_source/gsmtap.py:48:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/apdu_source/gsmtap.py:44:20: W0612: Unused variable 'addr' (unused-variable) pySim/apdu_source/gsmtap.py:22:0: C0411: first party import "from pySim.apdu.ts_102_221 import ApduCommands as UiccApduCommands" should be placed before "from . import ApduSource, PacketType, CardReset" (wrong-import-order) pySim/apdu_source/gsmtap.py:23:0: C0411: first party import "from pySim.apdu.ts_31_102 import ApduCommands as UsimApduCommands" should be placed before "from . import ApduSource, PacketType, CardReset" (wrong-import-order) pySim/apdu_source/gsmtap.py:24:0: C0411: first party import "from pySim.apdu.global_platform import ApduCommands as GpApduCommands" should be placed before "from . import ApduSource, PacketType, CardReset" (wrong-import-order) pySim/apdu_source/gsmtap.py:19:0: W0611: Unused GsmtapMessage imported from pySim.gsmtap (unused-import)
Commit
9bc016e7770fa774695ad35fe8390d85ccc5a755
by laforge
pylint: apdu_source/pyshark_gsmtap
pySim/apdu_source/pyshark_gsmtap.py:90:0: C0305: Trailing newlines (trailing-newlines) pySim/apdu_source/pyshark_gsmtap.py:68:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/apdu_source/pyshark_gsmtap.py:30:0: C0411: first party import "from pySim.apdu.ts_102_221 import ApduCommands as UiccApduCommands" should be placed before "from . import ApduSource, PacketType, CardReset" (wrong-import-order) pySim/apdu_source/pyshark_gsmtap.py:31:0: C0411: first party import "from pySim.apdu.ts_31_102 import ApduCommands as UsimApduCommands" should be placed before "from . import ApduSource, PacketType, CardReset" (wrong-import-order) pySim/apdu_source/pyshark_gsmtap.py:32:0: C0411: first party import "from pySim.apdu.global_platform import ApduCommands as GpApduCommands" should be placed before "from . import ApduSource, PacketType, CardReset" (wrong-import-order) pySim/apdu_source/pyshark_gsmtap.py:19:0: W0611: Unused import sys (unused-import) pySim/apdu_source/pyshark_gsmtap.py:21:0: W0611: Unused pprint imported from pprint as pp (unused-import) pySim/apdu_source/pyshark_gsmtap.py:25:0: W0611: Unused b2h imported from pySim.utils (unused-import) pySim/apdu_source/pyshark_gsmtap.py:26:0: W0611: Unused Tpdu imported from pySim.apdu (unused-import)
Commit
9ef65099d26008c631d33dd4dd217e0808052962
by laforge
pylint: apdu/__init__.py
pySim/apdu/__init__.py:41:0: W0105: String statement has no effect (pointless-string-statement) pySim/apdu/__init__.py:55:4: C0204: Metaclass class method __new__ should have 'mcs' as first argument (bad-mcs-classmethod-argument) pySim/apdu/__init__.py:187:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/apdu/__init__.py:200:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/__init__.py:208:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/__init__.py:216:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/__init__.py:224:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/__init__.py:239:11: C0117: Consider changing "not 'p1' in self.cmd_dict" to "'p1' not in self.cmd_dict" (unnecessary-negation) pySim/apdu/__init__.py:295:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/__init__.py:313:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/__init__.py:416:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/__init__.py:429:12: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/__init__.py:455:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/__init__.py:31:0: C0411: standard import "import typing" should be placed before "from termcolor import colored" (wrong-import-order) pySim/apdu/__init__.py:32:0: C0411: standard import "from typing import List, Dict, Optional" should be placed before "from termcolor import colored" (wrong-import-order)
Commit
e6e74229c9bba2f6eebe118a2f4626e9f4110dd1
by laforge
pylint: pySim/esim/bsp.py
pySim/esim/bsp.py:1:0: C0114: Missing module docstring (missing-module-docstring) pySim/esim/bsp.py:28:0: C0413: Import "import abc" should be placed at the top of the module (wrong-import-position) pySim/esim/bsp.py:29:0: C0413: Import "from typing import List" should be placed at the top of the module (wrong-import-position) pySim/esim/bsp.py:30:0: C0413: Import "import logging" should be placed at the top of the module (wrong-import-position) pySim/esim/bsp.py:33:0: C0413: Import "from cryptography.hazmat.primitives import hashes" should be placed at the top of the module (wrong-import-position) pySim/esim/bsp.py:34:0: C0413: Import "from cryptography.hazmat.primitives.kdf.x963kdf import X963KDF" should be placed at the top of the module (wrong-import-position) pySim/esim/bsp.py:36:0: C0413: Import "from Cryptodome.Cipher import AES" should be placed at the top of the module (wrong-import-position) pySim/esim/bsp.py:37:0: C0413: Import "from Cryptodome.Hash import CMAC" should be placed at the top of the module (wrong-import-position) pySim/esim/bsp.py:39:0: C0413: Import "from pySim.utils import bertlv_encode_len, bertlv_parse_one, b2h" should be placed at the top of the module (wrong-import-position) pySim/esim/bsp.py:48:55: W0613: Unused argument 'padding' (unused-argument) pySim/esim/bsp.py:55:45: W0613: Unused argument 'multiple' (unused-argument) pySim/esim/bsp.py:84:8: W0107: Unnecessary pass statement (unnecessary-pass) pySim/esim/bsp.py:89:8: W0107: Unnecessary pass statement (unnecessary-pass) pySim/esim/bsp.py:94:8: W0107: Unnecessary pass statement (unnecessary-pass) pySim/esim/bsp.py:169:8: W0107: Unnecessary pass statement (unnecessary-pass) pySim/esim/bsp.py:292:8: W0612: Unused variable 'tdict' (unused-variable) pySim/esim/bsp.py:292:15: W0612: Unused variable 'l' (unused-variable) pySim/esim/bsp.py:292:23: W0612: Unused variable 'remain' (unused-variable)
Commit
f235b799e96f2ac07dfcbb8de4a0a9be62952599
by laforge
pylint: esim/x509_cert.py
pySim/esim/x509_cert.py:70:4: W0107: Unnecessary pass statement (unnecessary-pass) pySim/esim/x509_cert.py:91:20: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck) pySim/esim/x509_cert.py:105:28: W3101: Missing timeout argument for method 'requests.get' can cause your program to hang indefinitely (missing-timeout) pySim/esim/x509_cert.py:163:0: C0413: Import "from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature" should be placed at the top of the module (wrong-import-position) pySim/esim/x509_cert.py:20:0: C0411: standard import "from typing import Optional, List" should be placed before "import requests" (wrong-import-order) pySim/esim/x509_cert.py:163:0: C0411: third party import "from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature" should be placed before "from pySim.utils import b2h" (wrong-import-order) pySim/esim/x509_cert.py:163:0: C0412: Imports from package cryptography are not grouped (ungrouped-imports) pySim/esim/x509_cert.py:22:0: W0611: Unused padding imported from cryptography.hazmat.primitives.asymmetric (unused-import) pySim/esim/x509_cert.py:24:0: W0611: Unused InvalidSignature imported from cryptography.exceptions (unused-import)
Commit
1258e464a1ac50c9eb32ea1d532f0d22c764af66
by laforge
pylint: esim/saip/personalization.py
pySim/esim/saip/personalization.py:104:0: W0311: Bad indentation. Found 17 spaces, expected 16 (bad-indentation) pySim/esim/saip/personalization.py:105:0: W0311: Bad indentation. Found 17 spaces, expected 16 (bad-indentation) pySim/esim/saip/personalization.py:151:0: C0305: Trailing newlines (trailing-newlines) pySim/esim/saip/personalization.py:36:4: C0204: Metaclass class method __new__ should have 'mcs' as first argument (bad-mcs-classmethod-argument) pySim/esim/saip/personalization.py:56:4: W0237: Parameter 'pe_seq' has been renamed to 'pes' in overriding 'Iccid.apply' method (arguments-renamed) pySim/esim/saip/personalization.py:19:0: W0611: Unused Optional imported from typing (unused-import)
Commit
5f6b64dc2591ee4fb47c31d2aa4cfc5fbbad9761
by laforge
pylint: esim/saip/templates.py
pySim/esim/saip/templates.py:106:0: R1707: Disallow trailing comma tuple (trailing-comma-tuple) pySim/esim/saip/templates.py:56:37: C0121: Comparison 'self.fid != None' should be 'self.fid is not None' (singleton-comparison) pySim/esim/saip/templates.py:57:28: C0121: Comparison 'self.arr != None' should be 'self.arr is not None' (singleton-comparison) pySim/esim/saip/templates.py:58:37: C0121: Comparison 'self.sfi != None' should be 'self.sfi is not None' (singleton-comparison) pySim/esim/saip/templates.py:96:11: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck) pySim/esim/saip/templates.py:591:0: W1404: Implicit string concatenation found in list (implicit-str-concat)
Commit
530bf73cbcd7af3bfdf957d22e13690de935dc1a
by laforge
pylint: esim/saip/oid.py
pySim/esim/saip/oid.py:30:11: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck) pySim/esim/saip/oid.py:46:11: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck)
Commit
4c0b80415ea9f19f07600923db862952f63642c3
by laforge
pylint: global_platform/scp.py
pySim/global_platform/scp.py:27:0: W0404: Reimport 'Optional' (imported line 20) (reimported) pySim/global_platform/scp.py:157:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/global_platform/scp.py:165:8: W0107: Unnecessary pass statement (unnecessary-pass) pySim/global_platform/scp.py:182:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/global_platform/scp.py:189:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/global_platform/scp.py:266:4: W0221: Variadics removed in overriding 'SCP02._wrap_cmd_apdu' method (arguments-differ) pySim/global_platform/scp.py:298:4: W0237: Parameter 'rsp_apdu' has been renamed to 'apdu' in overriding 'SCP02.unwrap_rsp_apdu' method (arguments-renamed) pySim/global_platform/scp.py:314:7: C0121: Comparison 'l == None' should be 'l is None' (singleton-comparison) pySim/global_platform/scp.py:436:11: C0121: Comparison 'host_challenge == None' should be 'host_challenge is None' (singleton-comparison) pySim/global_platform/scp.py:506:4: W0237: Parameter 'rsp_apdu' has been renamed to 'apdu' in overriding 'SCP03.unwrap_rsp_apdu' method (arguments-renamed) pySim/global_platform/scp.py:27:0: C0411: standard import "from typing import Optional" should be placed before "from Cryptodome.Cipher import DES3, DES" (wrong-import-order)
Commit
4f3976d77f53967c17ff5e173641970ecc83d5db
by laforge
pylint: cdma_ruim.py
pySim/cdma_ruim.py:30:0: W0401: Wildcard import construct (wildcard-import) pySim/cdma_ruim.py:188:4: W0237: Parameter 'data_hex' has been renamed to 'resp_hex' in overriding 'CardProfileRUIM.decode_select_response' method (arguments-renamed) pySim/cdma_ruim.py:30:0: C0411: third party import "from construct import *" should be placed before "from pySim.utils import *" (wrong-import-order)
Commit
a5630dc45c23d395144728c522c59af496864dc3
by laforge
pylint: apdu/ts_102_221.py
pySim/apdu/ts_102_221.py:60:16: R1724: Unnecessary "else" after "continue", remove the "else" and de-indent the code inside it (no-else-continue) pySim/apdu/ts_102_221.py:107:16: W0107: Unnecessary pass statement (unnecessary-pass) pySim/apdu/ts_102_221.py:294:8: R1703: The if statement can be replaced with 'return bool(test)' (simplifiable-if-statement) pySim/apdu/ts_102_221.py:294:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/ts_102_221.py:299:31: W0613: Unused argument 'lchan' (unused-argument) ... pySim/apdu/ts_102_221.py:389:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/apdu/ts_102_221.py:421:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/apdu/ts_102_221.py:425:12: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/apdu/ts_102_221.py:438:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/apdu/ts_102_221.py:26:0: C0411: standard import "from typing import Optional, Dict, Tuple" should be placed before "from construct import GreedyRange, Struct" (wrong-import-order)
Commit
a5fafe8b4857cbecb1bce8b47df2acf5712216d7
by laforge
pylint: ts_102_221.py
pySim/ts_102_221.py:20:0: W0622: Redefining built-in 'BlockingIOError' (redefined-builtin) pySim/ts_102_221.py:30:0: R0402: Use 'from pySim import iso7816_4' instead (consider-using-from-import) pySim/ts_102_221.py:20:0: W0401: Wildcard import construct (wildcard-import) pySim/ts_102_221.py:235:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/ts_102_221.py:272:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/ts_102_221.py:281:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/ts_102_221.py:484:12: W0715: Exception arguments suggest string formatting might be intended (raising-format-tuple) pySim/ts_102_221.py:486:12: W0715: Exception arguments suggest string formatting might be intended (raising-format-tuple) pySim/ts_102_221.py:488:12: W0715: Exception arguments suggest string formatting might be intended (raising-format-tuple) pySim/ts_102_221.py:523:11: C1802: Do not use `len(SEQUENCE)` without comparison to determine if a sequence is empty (use-implicit-booleaness-not-len) pySim/ts_102_221.py:647:0: W0613: Unused argument 'kwargs' (unused-argument) pySim/ts_102_221.py:747:19: W0612: Unused variable 'sw' (unused-variable) pySim/ts_102_221.py:26:0: C0411: third party import "from bidict import bidict" should be placed before "from pySim.construct import *" (wrong-import-order) pySim/ts_102_221.py:27:0: C0412: Imports from package pySim are not grouped (ungrouped-imports) pySim/ts_102_221.py:29:0: W0611: Unused match_sim imported from pySim.profile (unused-import) pySim/ts_102_221.py:34:0: W0611: Unused DF_GSM imported from pySim.ts_51_011 (unused-import) pySim/ts_102_221.py:34:0: W0611: Unused DF_TELECOM imported from pySim.ts_51_011 (unused-import)
Commit
8829f8e690180289b617b5e27f838600c1f054ee
by laforge
pylint: commands.py
pySim/commands.py:443:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/commands.py:446:0: C0325: Unnecessary parens after 'elif' keyword (superfluous-parens) pySim/commands.py:669:0: C0325: Unnecessary parens after 'elif' keyword (superfluous-parens) pySim/commands.py:27:0: W0622: Redefining built-in 'BlockingIOError' (redefined-builtin) pySim/commands.py:27:0: W0401: Wildcard import construct (wildcard-import) pySim/commands.py:30:0: W0404: Reimport 'Hexstr' (imported line 29) (reimported) pySim/commands.py:42:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/commands.py:48:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/commands.py:98:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/commands.py:114:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/commands.py:131:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/commands.py:223:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/commands.py:234:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/commands.py:252:11: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck) pySim/commands.py:271:11: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck) pySim/commands.py:274:18: W0612: Unused variable 'sw' (unused-variable) pySim/commands.py:326:16: W0707: Consider explicitly re-raising using 'raise ValueError('%s, failed to read (offset %d)' % (str_sanitize(str(e)), offset)) from e' (raise-missing-from) pySim/commands.py:386:16: W0707: Consider explicitly re-raising using 'raise ValueError('%s, failed to write chunk (chunk_offset %d, chunk_len %d)' % (str_sanitize(str(e)), chunk_offset, chunk_len)) from e' (raise-missing-from) pySim/commands.py:443:12: R1720: Unnecessary "elif" after "raise", remove the leading "el" from "elif" (no-else-raise) pySim/commands.py:521:14: R1714: Consider merging these comparisons with 'in' by using 'sw in ('62f1', '62f2')'. Use a set instead if elements are hashable. (consider-using-in) pySim/commands.py:532:11: R1701: Consider merging these isinstance calls to isinstance(data, (bytearray, bytes)) (consider-merging-isinstance) pySim/commands.py:666:8: R1720: Unnecessary "elif" after "raise", remove the leading "el" from "elif" (no-else-raise) pySim/commands.py:762:12: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/commands.py:776:12: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return)
Commit
f2322774c790ffbe6e7fda3c700fe355ac0e1ec3
by laforge
pylint: filesystem.py
pySim/filesystem.py:823:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/filesystem.py:849:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/filesystem.py:43:0: W0401: Wildcard import pySim.exceptions (wildcard-import) pySim/filesystem.py:74:45: C0121: Comparison 'fid == None' should be 'fid is None' (singleton-comparison) pySim/filesystem.py:94:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/filesystem.py:100:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/filesystem.py:149:8: W0105: String statement has no effect (pointless-string-statement) pySim/filesystem.py:170:11: C0121: Comparison 'self.parent == None' should be 'self.parent is None' (singleton-comparison) pySim/filesystem.py:283:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:309:8: W0246: Useless parent or super() delegation in method '__init__' (useless-parent-delegation) pySim/filesystem.py:314:15: C0117: Consider changing "not 'fid' in kwargs" to "'fid' not in kwargs" (unnecessary-negation) pySim/filesystem.py:317:24: R1735: Consider using '{}' instead of a call to 'dict'. (use-dict-literal) pySim/filesystem.py:418:11: C0121: Comparison 'name == None' should be 'name is None' (singleton-comparison) pySim/filesystem.py:427:11: C0121: Comparison 'sfid == None' should be 'sfid is None' (singleton-comparison) pySim/filesystem.py:452:28: R1735: Consider using '{}' instead of a call to 'dict'. (use-dict-literal) pySim/filesystem.py:508:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/filesystem.py:531:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/filesystem.py:576:8: W0246: Useless parent or super() delegation in method '__init__' (useless-parent-delegation) pySim/filesystem.py:599:19: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:609:19: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:620:19: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:633:28: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:642:41: W0613: Unused argument 'opts' (unused-argument) pySim/filesystem.py:644:24: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:696:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:723:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:749:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:777:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:797:8: W0246: Useless parent or super() delegation in method '__init__' (useless-parent-delegation) pySim/filesystem.py:822:23: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:838:19: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:844:34: W0613: Unused argument 'opts' (unused-argument) pySim/filesystem.py:848:23: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:866:23: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:878:19: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:893:28: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:910:24: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:967:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:995:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:1023:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:1051:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:1114:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:1141:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:1167:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:1194:8: R1705: Unnecessary "elif" after "return", remove the leading "el" from "elif" (no-else-return) pySim/filesystem.py:1226:8: W0246: Useless parent or super() delegation in method '__init__' (useless-parent-delegation) pySim/filesystem.py:1236:19: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:1239:35: W0613: Unused argument 'opts' (unused-argument) pySim/filesystem.py:1252:19: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:1263:19: W0612: Unused variable 'sw' (unused-variable) pySim/filesystem.py:1315:24: R1735: Consider using '{}' instead of a call to 'dict'. (use-dict-literal) pySim/filesystem.py:35:0: C0411: standard import "import argparse" should be placed before "import cmd2" (wrong-import-order) pySim/filesystem.py:37:0: C0411: standard import "from typing import cast, Optional, Iterable, List, Dict, Tuple, Union" should be placed before "import cmd2" (wrong-import-order) pySim/filesystem.py:27:0: W0611: Unused import code (unused-import) pySim/filesystem.py:34:0: W0611: Unused with_argparser imported from cmd2 (unused-import) pySim/filesystem.py:41:0: W0611: Unused i2h imported from pySim.utils (unused-import) pySim/filesystem.py:41:0: W0611: Unused Hexstr imported from pySim.utils (unused-import) pySim/filesystem.py:44:0: W0611: Unused js_path_find imported from pySim.jsonpath (unused-import) pySim/filesystem.py:43:0: W0614: Unused import(s) NoCardError, ProtocolError, ReaderError and SwMatchError from wildcard import of pySim.exceptions (unused-wildcard-import)
Commit
f2b20bf6ca4964c6abf4b5622a045d315f23cdcb
by laforge
pylint: utils.py
pySim/utils.py:903:0: C0325: Unnecessary parens after 'if' keyword (superfluous-parens) pySim/utils.py:153:16: R1719: The if expression can be replaced with 'bool(test)' (simplifiable-if-expression) pySim/utils.py:158:16: R1719: The if expression can be replaced with 'bool(test)' (simplifiable-if-expression) pySim/utils.py:166:16: R1719: The if expression can be replaced with 'bool(test)' (simplifiable-if-expression) pySim/utils.py:222:19: R1719: The if expression can be replaced with 'not test' (simplifiable-if-expression) pySim/utils.py:237:18: R1719: The if expression can be replaced with 'bool(test)' (simplifiable-if-expression) pySim/utils.py:246:19: R1719: The if expression can be replaced with 'not test' (simplifiable-if-expression) pySim/utils.py:279:11: W0612: Unused variable 'remainder' (unused-variable) pySim/utils.py:541:7: R1714: Consider merging these comparisons with 'in' by using 'eutran_bits in (16384, 28672)'. Use a set instead if elements are hashable. (consider-using-in) pySim/utils.py:550:7: R1714: Consider merging these comparisons with 'in' by using 'gsm_bits in (128, 140)'. Use a set instead if elements are hashable. (consider-using-in) pySim/utils.py:614:7: C0121: Comparison 'imsi == None' should be 'imsi is None' (singleton-comparison) pySim/utils.py:627:7: C0121: Comparison 'imsi == None' should be 'imsi is None' (singleton-comparison) pySim/utils.py:733:7: R1714: Consider merging these comparisons with 'in' by using 'msisdn in ('', '+')'. Use a set instead if elements are hashable. (consider-using-in) pySim/utils.py:774:8: W0612: Unused variable 'try_encode' (unused-variable) pySim/utils.py:803:16: W0707: Consider explicitly re-raising using 'except ValueError as exc' and 'raise ValueError('PIN-ADM needs to be hex encoded using this option') from exc' (raise-missing-from) pySim/utils.py:801:16: W0612: Unused variable 'try_encode' (unused-variable) pySim/utils.py:821:7: C1802: Do not use `len(SEQUENCE)` without comparison to determine if a sequence is empty (use-implicit-booleaness-not-len) pySim/utils.py:836:4: W0612: Unused variable 'e' (unused-variable) pySim/utils.py:892:7: C0121: Comparison 'str_list == None' should be 'str_list is None' (singleton-comparison) pySim/utils.py:991:11: R1701: Consider merging these isinstance calls to isinstance(o, (BytesIO, bytearray, bytes)) (consider-merging-isinstance)
Commit
6db681924cffc9f36c9fcdf1567a8cadcae5390c
by laforge
pylint: tlv.py
pySim/tlv.py:29:0: W0401: Wildcard import pySim.exceptions (wildcard-import) pySim/tlv.py:43:4: C0204: Metaclass class method __new__ should have 'mcs' as first argument (bad-mcs-classmethod-argument) pySim/tlv.py:66:4: C0204: Metaclass class method __new__ should have 'mcs' as first argument (bad-mcs-classmethod-argument) pySim/tlv.py:89:11: C0121: Comparison 'self.decoded == None' should be 'self.decoded is None' (singleton-comparison) pySim/tlv.py:170:8: R1703: The if statement can be replaced with 'return bool(test)' (simplifiable-if-statement) pySim/tlv.py:202:4: W0246: Useless parent or super() delegation in method '__init__' (useless-parent-delegation) pySim/tlv.py:257:4: W0246: Useless parent or super() delegation in method '__init__' (useless-parent-delegation) pySim/tlv.py:308:4: W0246: Useless parent or super() delegation in method '__init__' (useless-parent-delegation) pySim/tlv.py:383:15: C0121: Comparison 'tag == None' should be 'tag is None' (singleton-comparison) pySim/tlv.py:382:17: W0612: Unused variable 'r' (unused-variable) pySim/tlv.py:389:16: W0612: Unused variable 'dec' (unused-variable) pySim/tlv.py:461:22: R1718: Consider using a set comprehension (consider-using-set-comprehension) pySim/tlv.py:473:0: C0206: Consider iterating with .items() (consider-using-dict-items) pySim/tlv.py:473:58: C0201: Consider iterating the dictionary directly instead of calling .keys() (consider-iterating-dictionary) pySim/tlv.py:20:0: W0611: Unused Optional imported from typing (unused-import) pySim/tlv.py:20:0: W0611: Unused Dict imported from typing (unused-import) pySim/tlv.py:20:0: W0611: Unused Any imported from typing (unused-import) pySim/tlv.py:21:0: W0611: Unused bidict imported from bidict (unused-import) pySim/tlv.py:28:0: W0611: Unused LV imported from pySim.construct (unused-import) pySim/tlv.py:28:0: W0611: Unused HexAdapter imported from pySim.construct (unused-import) pySim/tlv.py:28:0: W0611: Unused BcdAdapter imported from pySim.construct (unused-import) pySim/tlv.py:28:0: W0611: Unused BitsRFU imported from pySim.construct (unused-import) pySim/tlv.py:28:0: W0611: Unused GsmStringAdapter imported from pySim.construct (unused-import) pySim/tlv.py:29:0: W0614: Unused import(s) NoCardError, ProtocolError, ReaderError and SwMatchError from wildcard import of pySim.exceptions (unused-wildcard-import)
Commit
55be7d48ee8663d382b3565d51f94387c0ccab24
by laforge
pylint: construct.py
pySim/construct.py:47:0: W0311: Bad indentation. Found 16 spaces, expected 12 (bad-indentation) pySim/construct.py:59:0: W0311: Bad indentation. Found 16 spaces, expected 12 (bad-indentation) pySim/construct.py:82:0: W0311: Bad indentation. Found 16 spaces, expected 12 (bad-indentation) pySim/construct.py:1:0: C0114: Missing module docstring (missing-module-docstring) pySim/construct.py:14:0: W0105: String statement has no effect (pointless-string-statement) pySim/construct.py:178:29: W0613: Unused argument 'instr' (unused-argument) pySim/construct.py:199:15: C0121: Comparison 'codepoint_prefix == None' should be 'codepoint_prefix is None' (singleton-comparison) pySim/construct.py:269:15: C0121: Comparison 'v == False' should be 'v is False' if checking for the singleton value False, or 'not v' if testing for falsiness (singleton-comparison) pySim/construct.py:271:17: C0121: Comparison 'v == True' should be 'v is True' if checking for the singleton value True, or 'v' if testing for truthiness (singleton-comparison) pySim/construct.py:385:15: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck) pySim/construct.py:392:15: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck) pySim/construct.py:408:11: C0123: Use isinstance() rather than type() for a typecheck. (unidiomatic-typecheck) pySim/construct.py:421:7: R1701: Consider merging these isinstance calls to isinstance(c, (Container, dict)) (consider-merging-isinstance) pySim/construct.py:444:11: R1729: Use a generator instead 'all(v == 255 for v in raw_bin_data)' (use-a-generator) pySim/construct.py:434:81: W0613: Unused argument 'exclude_prefix' (unused-argument) pySim/construct.py:544:12: W0707: Consider explicitly re-raising using 'raise IntegerError(str(e), path=path) from e' (raise-missing-from) pySim/construct.py:561:8: R1731: Consider using 'nbytes = max(nbytes, minlen)' instead of unnecessary if block (consider-using-max-builtin) pySim/construct.py:573:12: W0707: Consider explicitly re-raising using 'raise IntegerError(str(e), path=path) from e' (raise-missing-from) pySim/construct.py:3:0: C0411: standard import "import typing" should be placed before "from construct.lib.containers import Container, ListContainer" (wrong-import-order) pySim/construct.py:10:0: C0411: third party import "import gsm0338" should be placed before "from pySim.utils import b2h, h2b, swap_nibbles" (wrong-import-order) pySim/construct.py:11:0: C0411: standard import "import codecs" should be placed before "from construct.lib.containers import Container, ListContainer" (wrong-import-order) pySim/construct.py:12:0: C0411: standard import "import ipaddress" should be placed before "from construct.lib.containers import Container, ListContainer" (wrong-import-order) pySim/construct.py:7:0: W0611: Unused BitwisableString imported from construct.core (unused-import)
Commit
908634396ff6a6d2adf907576523c449d9a8dbab
by laforge
pylint: global_platform/__init__.py
pySim/global_platform/__init__.py:468:4: W0221: Number of parameters was 2 in 'CardFile.decode_select_response' and is now 1 in overriding 'ADF_SD.decode_select_response' method (arguments-differ) pySim/global_platform/__init__.py:473:8: W0246: Useless parent or super() delegation in method '__init__' (useless-parent-delegation) pySim/global_platform/__init__.py:491:19: W0612: Unused variable 'sw' (unused-variable) pySim/global_platform/__init__.py:528:22: W0612: Unused variable 'sw' (unused-variable) pySim/global_platform/__init__.py:559:12: C0200: Consider using enumerate instead of iterating with range and len (consider-using-enumerate) pySim/global_platform/__init__.py:587:18: W0612: Unused variable 'sw' (unused-variable) pySim/global_platform/__init__.py:617:20: W0612: Unused variable 'dec' (unused-variable) pySim/global_platform/__init__.py:645:12: W0612: Unused variable 'data' (unused-variable) pySim/global_platform/__init__.py:645:18: W0612: Unused variable 'sw' (unused-variable) pySim/global_platform/__init__.py:746:15: C0121: Comparison 'opts.key_id == None' should be 'opts.key_id is None' (singleton-comparison) pySim/global_platform/__init__.py:746:39: C0121: Comparison 'opts.key_ver == None' should be 'opts.key_ver is None' (singleton-comparison) pySim/global_platform/__init__.py:750:15: C0121: Comparison 'opts.key_id != None' should be 'opts.key_id is not None' (singleton-comparison) pySim/global_platform/__init__.py:752:15: C0121: Comparison 'opts.key_ver != None' should be 'opts.key_ver is not None' (singleton-comparison) pySim/global_platform/__init__.py:787:16: W0612: Unused variable 'rsp_hex' (unused-variable) pySim/global_platform/__init__.py:787:25: W0612: Unused variable 'sw' (unused-variable) pySim/global_platform/__init__.py:836:30: W0612: Unused variable 'sw' (unused-variable) pySim/global_platform/__init__.py:839:12: W0612: Unused variable 'ext_auth_resp' (unused-variable) pySim/global_platform/__init__.py:846:33: W0613: Unused argument 'opts' (unused-argument) pySim/global_platform/__init__.py:878:15: R1716: Simplify chained comparison between the operands (chained-comparison) pySim/global_platform/__init__.py:886:29: W0613: Unused argument 'kvn' (unused-argument) pySim/global_platform/__init__.py:893:0: C0413: Import "from Cryptodome.Cipher import DES, DES3, AES" should be placed at the top of the module (wrong-import-position) pySim/global_platform/__init__.py:23:0: C0411: standard import "from typing import Optional, List, Dict, Tuple" should be placed before "from construct import Optional as COptional" (wrong-import-order) pySim/global_platform/__init__.py:24:0: C0411: standard import "from copy import deepcopy" should be placed before "from construct import Optional as COptional" (wrong-import-order) pySim/global_platform/__init__.py:893:0: C0411: third party import "from Cryptodome.Cipher import DES, DES3, AES" should be placed before "from pySim.global_platform.scp import SCP02, SCP03" (wrong-import-order) pySim/global_platform/__init__.py:893:0: C0412: Imports from package Cryptodome are not grouped (ungrouped-imports)
Commit
1432af51500de2b06cfc6861416e8e29128c05fd
by laforge
Add terminal_capability command to send TERMINAL CAPABILITY
TS 102 221 specifies a TERMINAL CAPABILITY command using which the terminal (Software + hardware talking to the card) can expose their capabilities. This is also used in the eUICC universe to let the eUICC know which features are supported.
Commit
979c837286d3e5fa41322d2f97c4a31494cb5da5
by laforge
Dynamically determine maximum CMD data length depending on SCP
If we're using a Secure Channel Protocol, this will add overhead in terms of the C-MAC appended to the C-APDU. This means in turn that the useable length of the data field shrinks by a certain number of bytes.
Let's make sure the SCP instances expose an 'overhead' property of how much overhead they add - and that other commands use this to determine the maximum command data field length.
Commit
d16a20ccc3e67ffab1142d4f0541989ccc36a7ec
by laforge
saip: profile processing; merging with templates
Introduce code that makes use of the information from pySim.esim.saip.templates to build a complete representation of a file by merging the template with the ProfileElement decribing the file.
This happens within the class pySim.esim.saip.File, whose instances are created from ProfileElement + Template.
Commit
5ff0bafcdab012ceaaa5f9372d3014d50145db07
by laforge
pylint: esim/saip/__init__.py
pySim/esim/saip/__init__.py:28:0: R0402: Use 'from pySim.esim.saip import templates' instead (consider-using-from-import) pySim/esim/saip/__init__.py:166:8: R1705: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it (no-else-return) pySim/esim/saip/__init__.py:206:4: W0612: Unused variable 'tagdict' (unused-variable) pySim/esim/saip/__init__.py:273:23: C1802: Do not use `len(SEQUENCE)` without comparison to determine if a sequence is empty (use-implicit-booleaness-not-len)
Commit
7d88b076ad69932e560a077124f20e3e475ad89e
by laforge
pylint: esim/saip/validation.py
pySim/esim/saip/validation.py:95:42: C0117: Consider changing "not not ('usim' in m_svcs or 'isim' in m_svcs)" to "'usim' in m_svcs or 'isim' in m_svcs" (unnecessary-negation) pySim/esim/saip/validation.py:129:0: C0305: Trailing newlines (trailing-newlines)
Commit
aa76546d165b54bd1113d6e38e722543be1069b4
by laforge
osmo-smdpp: Add TS.48 profiles modified for unique ICCIDs
The original TS.48 profiles have shared/overlapping ICCIDs meaning you can always install one of them on a given eUICC. Let's add a set of modified TS.48 profiles so you can install any number of them in parallel on a single eUICC, switching between them via your LPA.
Commit
2de552e7123b16a54129ba8cfde5a1a25a09df6b
by laforge
saip.personalization: differentiate input_value from value
When personalizing e.g. the ICCID, the input_value is the raw incrementing counter. From that, we calculate the Luhn check digit, and that "output" value is what we'll put in to the EF.ICCID specific encoder.
However, we also store that output value in the instance in order to generate the output CSV file containig the card-specific personalization data.
The hex string of the generated transactionId contains lowercase hex digits. However SGP.22 explicitly spcifies to use uppercase hex digits when using JSON fromatted messages. See section 6.5.2.6 for example.
Commit
24a7f168bd53e97305d3dc2dea7b0d4bb28c20ab
by laforge
pcsc: open reader/card in EXCLUSIVE mode by default
There was a support request hinting that other applications concurrently accessed the SIM and were messing up the card state while pySim-shell was running.
Let's avoid such situations by opening the card/reader in EXCLUSIVE mode by default. If somebody really has a special use case, they can now add the --pcsc-shared flag to restore the legacy behavior (SHARED mode).
Commit
7aeeb4f4755094c4bafc1a23fd76b9fba9edb42f
by laforge
Add funding link to github mirror
see https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository
Commit
b2b29cfed1d0b23d004b3ec122c7c9d1c51f4d49
by laforge
esim.es2p: Permit ApiParamInteger to be an actual integer
Usually, the specifications say that the integer type is actually transmitted as a JSON string type. However, it seems some implementations do return a native JSON integer type. Let's be tolerant in that regard.
Commit
1d1ba8e4cc0cb8c1f862dad04b26e5d4786b924d
by laforge
esim.esp2: Allow HTTP methods other than POST
While all official/standardized ES2+ API functions use POST, there are some vendor-specific extensions using different HTTP methods. Be flexible enough to allow derived classes to easily specify other methods.
Commit
57df6f6e6856c5633816a901dda3d17e77fcce18
by laforge
filesystem: Enforce lower-case hex AID
our utils.b2h() returns values in lower-case hex string notation, so let's make sure the CardADF and CardApplication AID values are also stored in lower case notation, othewise the matching baesd on AIDs returned from the card will not work, specifically as we use uppercase AIDs in pySim.euicc for CardApplicationECASD and CardApplicationISDR.
Rather than change those two instances, let's solve it in a generic way.
We already do the same for the CardFile.fid member.
Commit
a644fecc01af11534d65704e1cc302f47f18fc36
by laforge
pySim.global_platform: Fix key encryption with DEK
When a SCP is active, the DEK is used to encrypt any key material that's installed using PUT KEY. The code prior to this patch fails to handle this case as it calls the encrypt_key() method on the wrong object.
Commit
c3d04ab19306c93c9d6af60d185214799700478a
by laforge
euicc.py: Resolve possible variable use before assignment
pySim/euicc.py:436:31: E0606: Possibly using variable 'p_id' before assignment (possibly-used-before-assignment) pySim/euicc.py:455:31: E0606: Possibly using variable 'p_id' before assignment (possibly-used-before-assignment) pySim/euicc.py:473:31: E0606: Possibly using variable 'p_id' before assignment (possibly-used-before-assignment)
Commit
daeba3c1fb4e3e73293dbb546af686b8101bbc2a
by laforge
sysmocom_sjs2: Make sure 'Const' is imported
File "/crypt/space/home/laforge/projects/git/pysim/pySim/sysmocom_sja2.py", line 180, in __init__ self._construct = Struct(Const(b'\x82'), 'time_unit'/self.TimeUnit, 'value'/Int8ub, ^^^^^ NameError: name 'Const' is not defined
Commit
6add18ea087a0849307c0d0a3d41f8df5a8a82ac
by laforge
contrib/sim-rest-client: don't crash without args
When running without an argument, let argparse print a nice usage error:
$ ./sim-rest-client.py usage: sim-rest-client.py [-h] [-H HOST] [-p PORT] [-v] [-n SLOT_NR] {auth,info} ... sim-rest-client.py: error: the following arguments are required: {auth,info}
Instead of:
$ ./sim-rest-client.py Traceback (most recent call last): File "/usr/share/pysim/contrib/./sim-rest-client.py", line 185, in <module> main(sys.argv) File "/usr/share/pysim/contrib/./sim-rest-client.py", line 181, in main args.func(args) ^^^^^^^^^ AttributeError: 'Namespace' object has no attribute 'func'
Commit
a823ce89f6c79f4212e7cf52655e88cf38570eee
by laforge
pySim/commands: STATUS: Use indeterminate length Le/P3 == '00'
Let's have the card tell us what the length is by indicating '00' instead of stating 'FF'. This is better aligned with general practice and won't break assumptions in other parts of the code like SCP transport.
We used to re-encode those parts of a decoded ASN.1 struct that is cryptographically signed in the GSMA SGP.22 specification. However, if the received data follows a later spec and contains new/unknown records, then our poor-man's attempt at re-encoding will render a different binary, which in turn means the signature check will fail.
Let's instead do a manual step-by-step raw decode of the DER TLV structure to extract the actual binary information of parts of ASN.1 objects.
Commit
64a5901c4c42a2ca5ef8071cdf938e9e59f25b07
by laforge
osmo-smdpp: Make error message more descriptive
Before this patch we had three different error causes that would cause a "Verification failed" error message. Let's state explicitly which part of verification did actually fail.
Commit
ddbfc043ac0fd977a0b18f4b729b9211eea4d432
by laforge
add globalplatform.uicc
GlobalPlatform has a [non-public] "UICC Configuration" spec, which defines some specific aspects of implementing GlobalPlatform in the context of an UICC. Let's add some python definitions about it.
Commit
ee7be445285334ccce1734e003c3222662d922a0
by laforge
utils: Introduce BER-TLV parsers that return raw tag or even raw TLV
In the eSIM RSP univers there are some rather ugly layering violatoins where ASN.1 cannot be parsed but we have to mess with raw TLVs and the details of DER encoding. Let's add two funtions that make it more convenient to work with this: They return the raw tag as integer, or even the entire encoded TLV rather than the value part only.
It's rather useful to have derived classes implementing specific functions related to that SAIP profile type. Let's introruce that concept and a first example for securityDomain, where methods allow checking/adding/removing support for SCPs.
Commit
0251367ddb11b533e6f9a8e70455dcd06f646945
by laforge
pySim.esim.saip: Meaningful constructors for [I]SD + SSD
So far the main use case was to read a ProfileElement-SD from a DER file. But when we want to construct one from scratch, we need to have the constructor put some meaningful [default] values into the class members.
Commit
1aaf978d9f1b290d13a82d7f1efef671f9fc4099
by laforge
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.
Commit
add30ecbfff32ee57a29b2524441e1c532d86fe7
by laforge
global_platform/euicc: Implement obtaining SCP keys from CardKeyProvider
Now that CardKeyProvider is capable of storing key materials transport-key-encrypted, we can use this functionality to look up the SCP02 / SCP03 key material for a given security domain.
This patch implements this for the ISD-R and ECASD using a look-up by EID inside the CSV.
Commit
16749075f9a8e10ec32df7d51058fbac4a5648e3
by laforge
pySim-trace: Add support for the TCA Loader log file format
The "TCA Loader" is a freeware utility program published by the Trusted Connectivity Alliance for testing SCP80, SCP81, SCP02 and SCP03 in UICCs. It can generate text log files of the APDUs it exchanges; let's add this file format to pySim-trace
Commit
0d1dea01dfea3e1cf85d5a2047097f3d84615b71
by laforge
add pySim.esim.es9p with definitions of the ES9+ HTTP Interface
Let's use the infrastructure of pySim.esim.http_json_api to define the ES9+ API Functions. This can in turn be used by clients or even osmo-smdpp can be ported over to using this infratructure rather than open-coding a lot of the encoding/decoding of API request/response parameters.
Commit
888c6e56473941e65c9213989e479b1288fb50d0
by laforge
add contrib/es9p_client: Perform ES9+ client functions like LPA+eUICC
This tool can be used to test the SM-DP+. It implements the full dance of all HTTPs API operations to get to the downloadProfile, and will decrypt the BPP to the UPP, which is then subsequently stored as file on disk.
Needless to say, this will only work if you have an eUICC certificate + private key that is compatible with the CI of your SM-DP+.
Commit
144bae3f37333cd30f1479d67d7e10641f76f46e
by laforge
pySim.tlv: Correctly parse COMPREHENSION-TLV without comprehension bit
The uppermost bit of COMPREHENSION-TLV tags indicates whether the recipient is required to "comprehend" that IE or not. So every IE actually has two tag values: one with and one without that bit set.
As all our existing TLV definitions of COMPR_TLV_IE have that bit set, let's assume this is the default, but use the same definition also for the situation where that bit is not set.
Commit
cdf661b24cfebb63b57405c2b55b3c42a8f277c8
by laforge
pySim.tlv.COMPR_TLV_IE: Patch comprehension bit if derived class misses it
Our current implementation assumes that all COMPR_TLV_IE are created with a raw tag value that has the comprehension bit set. Check for this during the class __new__ method and print a warning if we have to fix it up
Commit
3b4a673de4f79f5a5be0bd413b8991c1b12697cb
by laforge
add contrib/saip-tool.py
This is a tool to work with eSIM profiles in SAIP format. It allows to dump the contents, run constraint checkers as well as splitting of the PE-Sequence into the individual PEs.
So far we only implemented command encoding and response decoding. Let's also add command decoding, which is useful for example when decoding protocol traces.
Commit
b6532b56d2e78be6ac98977b82d63c65879abe34
by laforge
saip-tool: Add 'extract-apps' to dump all applications from eSIM profile
This new action can be used to dump all java applications as either raw IJC file or converted to CAP format (the usual format generated by JavaCard toolchains).
Commit
698886247f592cede824984723e78b41a0ef6b64
by laforge
pySim.tlv: Fix ComprTlvMeta() not passing kwargs to parent __new__
This fixes commit cdf661b24cfebb63b57405c2b55b3c42a8f277c8 "pySim.tlv.COMPR_TLV_IE: Patch comprehension bit if derived class misses it" where we introduce a comprehension-TLV specific derived metaclass, which forgets to pass the kwargs through to the parent metaclass.
Commit
200bf6eb8bb863737d3268152f25a45465f0af1a
by laforge
pySim.esim.saip: Meaningful defaults in PE Constructor + test
Let's make sure the constructor of ProfileElement subclasses set meaningful defaults to the self.decoded member, so that the to_der() method can actually encode it. This is required when constructing a profile from scratch, as opposed to loading an existing one from DER.
Also, add a test to verify that the encoder passes without exception; doesn't test the generated binary data.
Commit
b5679386d7073652c2784133319aa8fe7cad7344
by laforge
pySim.esim.saip: Add methods to rebuild "mandatory" lists in ProfileHeader
The ProfileHeader PE contain lists of template-oids and services that are mandatory in this profile. Let's add methods that can be used to (re-) compute those lists based on the actual PE contents of the sequence.
The idea is that during programmatic construction of a profile, those methods would be called after appending all PEs, just before encoding the profile as DER.
Commit
1c2ec93164c6f88f7c3388318c45dc03bc4cb0fb
by laforge
pySim.tlv: Add COMPACT_TLV_IE TLV variant
the COMPACT-TLV variant is a TLV variant that ISO7816 uses for encoding tag and length into a single octet. This is used (for example) in ATR historical bytes.
Let's add support for this to our pySim TLV encoder/decoder.
Commit
dacacd206df0fa4bbb791135aed45bd3363bd555
by laforge
pySim.ota: Handle cases where 'secured_data' is empty
while it's true that in situations where response_status == 'por_ok' we are guaranteed to have a 'secured_data' key in the dict, its value could well be b'', which in turn causes us to run into an exception, calling a decoder on an empty byte value; let's avoid that.
Commit
c805f00bff35904886d4623205c9ab756efa9c8b
by laforge
transport: Implement treatment of 62xx and 63xx warning/error responses
TS 102 221 specifies that (in case of a class 4 command) and as SW 62xx or 63xx, we should send a GET RESPONSE just like in the 61xx case in order to get the respective response.
As we don't really know if it's a case1/2/3/4 command in the pySim.transport, let's always send the GET RESPONSE in case SW 62xx or 63xx are received. It shouldn't hurt - in the worst case there's no response available...
Commit
96e2a521e942d676dd7bd2af9a403faa8a12d95d
by laforge
pySim.esim.http_json_api: 'header' is not always present in response
For example, the ES9+ handleNotification function is defined with an empty response body, so we cannot unconditionally assume that every HTTP response will contain a JSON "header" value.
Commit
0519e2b7e1c6470c67f6755eef3f74023c0ba734
by laforge
osmo-smdpp: Make sure to return empty HTTP response in handleNotification
SGP.22 is quite clear in that handleNotification shall return an empty HTTP response body. Let's make sure we comply to that and don't report a JSON response.
Commit
3ad3da89954d413f0aa47e5aff0e5bd4d2454607
by laforge
contrib/es9p_client: Add support for reporting notifications to SM-DP+
The ES9+ interface is not only used for downloading eSIM profiles, but it is also used to report back the installation result as well as profile management operations like enable/disable/delete.
Commit
e18586ddf0c8b5bddef570dcc080c71a603bafe5
by laforge
pySim.globalplatform: Add 'http' submodule for GP Amd B RAM over HTTPS
This implements the first parts of the "GlobalPlatform Remote Application Management over HTTP Card Specification v2.3 - Amendment B, Versoin 1.2". Specifically, this patch covers the TLV definitions for the OTA message used for HTTPS session triggering.
This also adds some more unit test coverage to pySim.cat, based on real-world data that was captured nested inside the HTTPS Administration session triggering parameters.
Commit
289d2343fa0f8c2f6df153d24b85593933efd2c5
by laforge
pySim.apdu: Refactor cmd_to_dict() method
Let's factor out the "automatic processing using _tlv / _construct" as a separate method. This way we enable a derived class to first call that automatic processing method, and then amend its output in a second step.
Commit
87b4f99a9085d9e760e63c7ff31d3c42a9697aaa
by laforge
pySim.apdu: Get rid of HexAdapter
In the past, we always wrapped a HexAdapter around bytes-like data in order to make sure it's printed as hex-digits. However, now that we are doing JSON output it's much easier to let the pySim.utils.JsonEncoder take care of this in a generic way.
We should do a similar migration all over pySim (pySim-shell, filesystem, etc.) - but for now only do it in the low-hanging fruit of pySim-trace aka pySim.apdu
Commit
c60944a7de24ce7bc5ffafed015a83e0f4f47c1a
by laforge
saip-tool: Fix TAR display for implicit TAR
Until Change-Id Ifba1048e3000829d54769b0420f5134e2f9b04e1 the TAR output was working for implicit tar. With said commit we fixed it for explicit tar but broke implicit tar.
With this commit it works for both implicit and explicit TAR.
Commit
7858f591fec4047a8083f9a837183589f76fc1ad
by laforge
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.
Commit
4fefac78b80447e7965583ad22a30f988b13b6f9
by laforge
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.
Commit
dff7bb0687009aafda6016bf5bdeb84e24402b3c
by laforge
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.
Commit
75a109419cc8b777d740208fd1d0f0c0ad7932aa
by laforge
pySim.tlv: Add convenience methods to IE class
The new methods allow programmatic resolution of nested IEs from a parent, assuming there's only one child of a given type (which is often but not always the case).
Commit
eda408fba3f6e3a78ba0316e0f1fa5d2ba386fe1
by laforge
pySim.commands: Don't convert SwMatchError to ValueError
In the read and write command implementations, we used to catch lower-layer exceptions (usually SwMatchError) and "translate" that into a value error, only to add more information to the exception. This meant that higher-layer code could no longer detect this was actually a SwMatchError exception type.
Let's instead use the add_note() method to amend the existing exception, rather than raising a new one of different type.
Commit
d29f244aad8a7e93f366ae299ce74b535e06697c
by laforge
pySim.tlv: Separate {to,from}_val_dict() from {to,from}_dict()
There are some situations where we want to work with a type-name-wrapped dict that includes the type information, and others where we don't want that. The main reason is that nested IEs can only be reconstructed if we can determine the type/class of the nested IE from the dict data.
Let's explicitly offer {to,from}_val_dict() methods that work with the value-part only
Commit
de5de0e9db3627e1c885603fa229986ee8e00098
by laforge
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.
Commit
d3fb38965b6c11461250ce22557f9200c70e7303
by laforge
ara_m: Fix pySim.tlv.IE.from_dict() calls
Historically, to_dict and from_dict were not symmetric; this has been fixed in I07e4feb3800b420d8be7aae8911f828f1da9dab8 in December 2023.
This however broke the ara_m legacy use of the from_dict() methods. We've just introduced a from_val_dict() method in I81654ea54aed9e598943f41a26a57dcc3a7f10c2, let's make use of it.
Commit
d81c2086c8866a74d7feb97b258e654545286d84
by laforge
pySim.tlv: Fix from_dict of nested TLVs
The existing logic is wrong. How we call from_dict() doesn't differ if a member IE itself contains a nested collection: We always must pass a single-entry dict with the snak-case name of the class to from_dict().
Commit
7c06bcdd571a907c1ca833be2019f947219c0c48
by laforge
Support EF.ICCID and EF.PL on classic TS 51.011 SIM
So far we only had the EF.ICCID and EF.PL within our UICC card profile. However, a classic GSM SIM card is not an UICC, so the CardProfileSIM also needs those files.
To avoid circular dependencies, move the definitions from ts_102_221.py to ts_51_011.py
Commit
d2254377b6204f244931c649251425ac0b234cad
by laforge
pySim.esim.saip.templates: Add a notion of the path of a file
The SAIP data format is inherently flat and doesn't intrinsically have an idea of the tree-like structure of a filesystem. However, if we want to (for example) convert a physical USIM into an eSIM profile, we need to find the template for a given file, where the file is identified by its path.
Let's expose a path property of the FileTemplate object, and populate that when creating the FileTemplate as part of a ProfileTemplate.
Commit
465d1a07e049cb65ef206bb60ef6cfa4ffabf975
by laforge
pySim.esim.saip.templates: Add SaipSpecVersion
The SAIP specification version implicitly determines which filesystem templates (or versions thereof) are supported. So if a given eUICC states it implements SAIP version 2.3.0, then we have to translate this into which template versions that means. The new SaipSpecVersion and its derived classes do exactly that.
Commit
7d9c6583efe8c6f5cb9f49718b85bef332915b7d
by laforge
pySim.cards: Make file_exists() check for activated/deactivated
The Card.file_exists() method is only called by legacy pySim-{read,prog} when it wants to determine if it can read/write a file. Therefore it actually doesn't only want to know if the file exists, but also if it's not deactivated.
filesystem: add placeholder export method in CardFile base class
We add export methods in subclasses of CardFile but the base class itself lacks an export method. To make the code more readable and to avoid unnecessary exceptions, les's add a default export method that just returns a comment.
ara_m: add export support for the ARA-M application
This patch adds an export method to the CardApplicationARAM class. This method reads the ARA-M configuration and transforms it into executeable command lines, which can be executed as a script later to restore an ARA-M configuration.
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)
runtime: add method to lookup a file by name without selecting it
In some cases it might come in handy to be able to lookup a random file in the file system tree before actually selecting it. This would be very useful in situations where we need to check the presence of the file or if we need to check certain file attributes before performing some task.
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.
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.
Commit
89dff98fb6bdfc3b606879a27905037e1f189ade
by laforge
pySim.esim.saip.templates: Introduce dependency/hierarchy information
The SAIP specification is very weird in a way that it treats the DF and EF descriptions as some kind of flat structure without describing the hierarchy. So when creating a DF, sometimes it should be created below the current DF, and sometimes it should be adjacent next to the current DF.
Let's introduce * a 'ppath' property of FileTemplate to indicate if a file is anything but a direct sibling of the 'base DF' of the PE * an 'extends' property of ProfileTemplate to indicate that a given template does not have its own 'base DF', but that its contents merely extends that of another ProfileTemplate * a 'parent' property of ProfileTemplate to indicate a parent ProfileTemplate below whose 'base DF' our files should be placed.
Commit
022d562ae1a4686f747292f79334b25266e83835
by laforge
pySim.ts_102_221: Make sure FileDescriptor for BER-TLV contains file_type
before this change, structure == 'ber_tlv' was missing the file_type == working_ef attribute. So for linear_fixed, transparent and cyclic, the file_type attribute was present, but for ber_tlv it was missing. This is illogical from a user point of vie and makes downstream code potentially more complex, as it cannot match on working_ef for all EF types.
Commit
97dfcaa9c72447d04390f48432baa7ba939bc96f
by laforge
pySim.filesystem: Permit Path object construction from FID integer list
we so far supported construction of the Path object from a string or a list of strings. Let's also add the option of constructing it from a path consisting of a list of integer FID values.
Commit
6d495fb24ddc34507a8777ec45372f8d020ced6e
by laforge
pySim.esim.saip: Improve File.from_template feature support
When populating a File from a FileTemplate, let's make sure we * correctly treat the maximum file size for BER-TLV files * respect the default value pattern / repeat pattern * respect the high_update flag.
Commit
b349149a88991d18ffc6ddf12fae29f9a309940e
by laforge
pySim.esim.saip: Back-reference from ProfileElement to ProfileElementSequence
Store a back-reference to the PE-Sequence in the PE object; this is neccessary for some upcoming patches, e.g. to determine the position in the sequence, access the global filesystem hierarchy, etc.
Commit
39613da6a74ac694550d5b0f24f1546923c6867b
by laforge
pySim.esim.saip: Fix key used in FsProfileElement.files2pe
The self.files member is a dict. Hence we should use those dict keys when [re]building the decoded dict. The previous code ignored it and re-constructed the key from File.pe_name - but that's not always identical.
Commit
c6f8457ff1c99065cc1bab79bf9bffcae7b9da6d
by laforge
pySim.esim.saip: maintain a parsed fileystem hierarchy
With this change, the ProfileElementSequence object will maintain a representation of the filesystem hierarchy of the eSIM profile. Every file that is added by a ProfileElement will add a FsNode into that tree, and each FsNode will point to the File object for the respective file.
This allows us to find files by their path, as well as add files by path.
Commit
89dbdbdccc37d885035fe79f2b4fe95235793dfd
by laforge
runtime: fix get_file_by_name
The method get_file_by_name compares the selectable directly with the given file name. This is not correct. The comparison should be with the path element from the pathlist.
Commit
1f920310793bbb2f6b977af88d09ee8d9a2ea95b
by laforge
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.
filesystem: add command to delete all contents from a BER-TLV EF
When working with BER-TLF files, we can only delete one tag at a time. There is no way to delete all tags at once. This may make working with BER-TLV files difficult, in particular when scripting is used and the script needs to start with an empty file. Also export has problems, since it does not reset the file before setting the new values there may be unexpected results in case there still tags in the file that are not set during import. To fill the gap, let's add a commandd that deletes all tags in a BER-TLV EF at once.
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.
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.
global_platform: fix help description for establish_scp03
The argument parser object for establish_scp03 (est_scp03_parser) is copied from est_scp02_parser. This object still has the .description property set, which is the description for establish_scp02. To get the description string that is defined in do_establish_scp03, we must remove the old description string first.
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.
The send_apdu* methods now support lchan patching, so there is no longer a need for computing the class byte manually (which is prone get forgotten) before calling a send_apdu*. It is now enough to supply an APDU that has a class byte with the default channel selected. This also means we do not need cla4lchan anymore, so let's restruture the code and get rid of it completely.
scp: fix key length in dek_encrypt and dek_decrypt
When creating the DES cipher object with DES.new, we use the property card_keys.dek. This property may hold a 16 byte key, but DES uses an 8 byte key (56 bit + 8 bit integrity). Pycryptodome does not automatically ignore excess key bytes. Instead it throws an exception. This means we need to make sure to supply only the first 8 bytes of card_keys.dek
See also: https://pycryptodome.readthedocs.io/en/latest/src/cipher/des.html
Commit
8680698f97478c631e324ea0a06aa5720691fb24
by laforge
suci-tutorial: fix incorrect hnet_pubkey value
The first hnet_pubkey value with the identifier 27 seems to be incorrect. It differs from the value suggested in 3GPP TS 31.121, section 4.9.4 and also does not work with the on card SUCI calculation.
The tutorial also contains a reference to 3GPP TS 33.501, Annex C.4. This spec specifies an ECIES Profile A and an ECIES Profile B. The tutorial recommends to use a key from profile B, but it actually uses a key from profile A.
tests: move pySim-trace test and its data into a sub directory
We currently have the test data for pySim-trace in pysim-testdata. This means we mix the test data with the data from our original pySim integration tests. This is very confusing. Let's put the test data and the testcase for pySim-trace into a dedicated sub directory.
tests: move pySim-prog test and its data into a sub directory
We currently have the shell script that performs the test in the tests directory and the related data in pysim-testdata directory. This is confusing, let's have evrything in a dedicated sub directory
suci-tutorial: put download links for specs to the front
The section Technical References has direct download links for the relevant specs. Then later in th Key Provisioning section another download link follows and another one is redundant. Let's put all download links into the Technical References section and then only use the spec numbers in the following. This way we have all download links in one location.
The test currently expects all reader slots to be populated. This means the cards may plugged into a random order, but there may not be any empty slots in the system at all. This requirement is easy to meet when each card has its own single-slot USB PCSC-reader, but as soon as multislot readers are used there may be some empty slots.
When the test detects a card, but does not find the .data faile for it, then it fails. This can be a problem in case we want to intentionally exclude a specific card model.
Commit
a3962b2076d157e075262c51e6c4d0a48ba12465
by laforge
Migrate over to using pyosmocom
We're creating a 'pyosmocom' pypi module which contains a number of core Osmocom libraries / interfaces that are not specific to SIM card stuff contained here.
The main modules moved in this initial step are pySim.tlv, pySim.utils and pySim.construct. utils is split, not all of the contents is unrelated to SIM Cards. The other two are moved completely.
Commit
52735f36859731703e0e6d6dbd2cffb8316613b8
by laforge
pySim.esim.saip: Fix weird DF names
Sometimes the struct member is called like df-telecom, but in other cases it's called df-df-saip with a double 'df' in front. That makes no sense, but we have to deal with it from our constructors...
Commit
bd7c21257c1328c984ac800a3b07c0055cb2c338
by laforge
commands: avoid double lchan patching, get rid of cla_byte getter+setter methods
The SimCardCommands has a cla_byte @property method, which automatically returns the lchan patched CLA byte. We use cla_byte property to build the UICC command APDUs inside SimCardCommands and then we hand the APDU over to the send_apdu* methods. The cla_byte @property method as well as the send_apdu* methods perform the lchan patching. This means the CLA byte gets patched twice, which is technically not an issue, but can be confusing when trying to understand the code.
To fix this, let's remove the @property methods and turn cla_byte into a normal property again. This is also more accurate since the cla_byte property originally was introduced to switch between UICC and classic SIM APDU commands, which have almost identcal APDUs.
Commit
f81331808f9b2dd8872e335a88995296bd169d0a
by laforge
pySim-shell: rework startup procedure and introduce non interactive mode
When pySim-shell is used in a scripted environment, we may easily get trapped in the pySim-shell prompt. This may happen in particular in case the script file is not executed due to problem with the reader initialization. In such a case pySim-shell will not exit automatically and the shellscript that was calling pySim-shell will stall indefinetly.
To make the use of pySim-shell more reliable in scripted environments, let's add a --noprompt option that ensures the interactive mode is never entered. Let's also exit with an appropriate return code in case of initialization errors, so that the calling script can know that something went wrong.
Commit
639806cc5aa97225a76ec1dc54ae687a897dd204
by laforge
pySim-shell: do not display 'AIDs:' when there are none
The command cardinfo also displays the AIDs of the card applications. However, on classic GSM sim cards there are no applications. In this case cardinfo will still display the string 'AIDs:', but it will of course not list any AIDs under this string.
Commit
398fdd7e8cba321a6cfcbda180d0287833b5a774
by laforge
pySim-shell: use upper case letters for positional arguments
When we define positional arguments for the argument parser, we usually use upper case letters only. However, there are some code locations that use lower case letters. Let's translate those to capital letters to have a consistent appeariance.
Commit
726097e51f1052b19bb2d8b5f0ef15c44f01b80c
by laforge
transport: define TERMINAL RESPONSE content within ProactiveHandler
So far the core proactive handling code would always generate a positive response, with no way for the ProactiveHandler call-back to influence that or to include additional IEs/TLVs.
Commit
5f2dfc28ff45d979d37d9f799ed2dc526c929f14
by laforge
pySim/profile: Change match_with_profile from static to class method
This was suggested by vyanitskiy during gerrit patch review in https://gerrit.osmocom.org/c/pysim/+/38049 in order to make the upcoming eUICC CardProfiles simpler.
Commit
72186cce84720ed4eee7f0d719a7c6ce91546644
by laforge
pySim.profile: Further refactor card <-> profile matching
The new architecture avoids sim/ruim/uicc specific methods in pySim.profile and instead moves the profile-specific code into the profile; it also solves everything within the class hierarchy, no need for global methods.
Commit
87e1ba6c184b9fb400875a9046cb8cd07ca45b6f
by laforge
update pyosmocom dependency to 0.0.3
0.0.3 fixes an important problem related to enabling callers of build_construct() to pass in a total_len value in order to specify the target output size.
Commit
3dc04969135132015b77904b997c0d7a71b6511f
by laforge
pySim-prog: treat --imsi and --iccid equally
When using a CSV file, we can either read the IMSI or ICCID from the CSV file before programming. However, should also be possible to supply both manually to identify the CSV file entry using the --imsi or --iccid option. This currently only works for the IMSI, but not for the ICCID.
Commit
3eb74829df34059c0dce23b7ca64579bc9c73058
by laforge
pySim-prog: fix commandline parameter check for CSV mode
The CSV mode needs one of the four additional parameters: --imsi --iccid, --read-iccid or --read-imsi. Also this check is unrelated to the batch mode. The CSV file parameter reading works independently from the batch mode.
Commit
94ecf9a92968861ad51d622e24e92d13c30326b6
by laforge
pySim-prog: rework documentation
The documentation for the classic pySim-prog application is a bit sparse. Let's rework it so that it includes the most important information that is required to operate pySim-prog. Let's also add a section about how the batch mode and CSV files are used.
Commit
9a6425b6f277e92745665907c33a0eb598e4554a
by laforge
runtime: add new API functions to get the record len and file size
We have an API function to get the number of records, let's now also add API functions to get the record length and the overall size of the currently selected file.
Commit
01a96cd8e464083bfc6c10631b38bc587a5bb101
by laforge
pySim-prog_test: individual ICCIDs for all cards
Our test cards need to stay recognizable, so it is important that each card has a unique ICCID. This means we must write an individual ICCID, when we test writing the ICCID.
pySim-shell: recognize ADP pins longer than 8 digits as hexadecimal
When a hexadecimal formatted ADM pin is retrieved via the card_key_provider, it still requires the --pin-is-hex parameter so that sanitize_pin_adm knows the correct format.
This unfortunately ruins the card_key_provider feature for all cards that use hexadecimal pins, because the --pin-is-hex would also be required in scripts, which makes a script either useable for cards with hexadecimal ADM or for for cards with ASCII ADM.
To minimize the problem, let's recognize all ADM pins longer than 8 digits as hexadecimal in case --pin-is-hex is not set.
This patch adds a comprehensive testsuite for pySim-shell. The testsuite is based on python's unittest framework in combination with pySim-shell scripts.
Commit
7b95fac0221dfb2b78d37da0165381408066ba71
by Oliver Smith
contrib/jenkins: add SKIP_CLEAN_WORKSPACE
In order to run this script from pyosmocom's contrib/jenkins.sh script, we want to skip the clean workspace step. Add an environment variable to do that.
The testcase euicc.test_list_and_rm_notif fails due to a problem with the eUICC. The eUICC reports the following error when a delete notification attempt is made:
"delete_notification_status": "undefinedError"
Let's temporarily disable this testcase until the problem is resolved.
Commit
78c22a7d635de4db9feaca36d85d89817494a425
by laforge
pySim-shell: New '-e' command line argument
Using '-e' it is possible to specify *multiple* pySim-shell commands which shall be executed at startup. This extends the current ability to execute just a single command.
filesystem: pass total_len to construct of when encoding file contents
In our construct models we frequently use a context parameter "total_len", we also pass this parameter to construct when we decode files, but we do not pass it when we generate files. This is a problem, because when total_len is used in the construct model, this parameter must be known also when decoding the file.
Let's make sure that the total_len is properly determined and and passed to construct (via pyosmocom).
ts_51_011: replace encoding of EF.MSISDN with construct model
The encoding of EF.MSISDN is currently done with enc_msisdn and dec_msisdn from utils.py. Let's replace this with a construct based model, similar to the one we already use with EF.ADN
The unittest for EF.ADN can run with _test_de_encode. However, the original test vectors seem to be from a card with a slightly larger record size, so they need a bit of re-alignment
utils: move enc_msisdn and dec_msisdn to legacy/utils.py
We now have a construct based encoder/decoder for the record content of EF.MSISDN. This means that we do not need the functions enc_msisdn and dec_msisdn in the non-legacy code anymore. We can now move both to legacy/utils.py.
Commit
7429bc0ca08d9eb9a65974e05d2d27e001edfd84
by laforge
tests: sanitize all cards before running tests
Even though our tests are written in a way that they shouldn't interfere with each other, it may happen that one testrun writes content to a file that upsets a different testrun. The resulting problems are often difficult to diagnose.
To minimize the problem, let's add code that can reset the cards to a defined state. This can be done using pySim-shell's export feature. We can generate a backup from a known good state and then play back the backup to reset files that have been changed. Files that didn't change will not be written thanks to the conserve_write feature of pySim-shell.
The build system uses a virtual environment, in which it installs pysim and its dependencies. This is done for the integration tests, but not when building the sphinx documentation. However, the documentation build process also invokes pysim code to generate documentation from the docstrings. This means we need pysim with all its dependencies for the doc building as well.
Commit
a8cfeb0111c263f1163b8a84e14ade5486fadb2a
by Oliver Smith
docs/Makefile: make SPHINXBUILD work in venv
sphinx-build doesn't use the PYTHONPATH from the venv, unless it runs as python3 -m sphinx.cmd.build. We need it to use the imports from PYTHONPATH, so we can update the pyosmocom version in requirements.txt in a patch, and this new version will be used in the jenkins job that runs during gerrit review. Otherwise the previously installed version (from the docker image) will be used.
The problems with test_list_and_rm_notif (see also change id I7d0b6a998499d84f0eb4e24592ad43210ac54806) are now resolved, so we can re-enable the testcase now.
global_platform: ensure ArgumentParser gets a list for choices
When we use the argument parser with choices, we sometimes use a list that we derive from a dictionary. However if we do that we still must ensure that we really put a list and not a dict_values or dict_keys class as parameter because this won't work any longer with cmd2 version 2.5.0
This adds a construct + pyosmocore.tlv based declarative encoder/decoder for the EF.EARFCNList file used in the context of NB-IoT in later release USIMs.
Commit
d8d52bdf77209eb392875d71b0713c233360d740
by laforge
pySim-shell_test/utils: delete log files in general
When we get rid of temporary files, we delete those using a wildcard, but for the logs from pySim-shell we explicitly memorize the name of the pySim-shell logfile and delete it later by this explicit name. This is not necessary, let's just delete all log files present using a wildcard.
When pySim-shell is called by a testcase, a logfile is createted. The logfile filename contains the testcase name. However, a testcase may run pySim-shell multiple times. In this case we overwrite the log from previous run. Let's use a counter to generate unique file names for each run, so that we won't lose logs from previous runs.
When we configure the tests to display file content, we only display files that we compare, let's also display log file contents from pySim-shell. This will be useful in situations where we only have log output from the tests, but no access to the file system of the test host.
The tests that check the establishment of a secure channel currently only test security level 3. Also the get_data command after it only tests data reception from the card.
Let's extend the test coverage and test the SCP establishment for security level 1 as well. Let's also add a get_status command to make sure sending data to the card also works (without exceptions).
when we sign and encrypt the APDU in _wrap_cmd_apdu (SCP03) we return an "mapdu" at the end. However, in the (unlikely?) case where self.do_cencand self.do_cmac are false, mapdu will be undeclared. In _wrap_cmd_apdu for SCP02 we just re-use the apdu variable and return it at the end, so when no encryption and no signing is applied, the APDU falls just through without any modifications. We should have the same mechanism for the SCP03 wrapping as well.
pySim-shell_test/utils: print logfile on all types of errors
When pySim-shell has problems starting up, it exits with an error code. This is detected by the testsuite, but it also causes an early exit, so that the log file content are not printed.
The "apdu" command allows us to send custom APDUs to a card. This command is often used in low level initialization scripts or tests. To stop the script execution in case of an error, the command allows us to specify a status word that must match the status word of the response. But we have no such mechanism for the response itself. Let's add another parameter where we can pass a regex that the response must match.
pySim-shell: fix reset command for no-profile mode
There are situations where no card profile can be determined. In this case no RuntimeState will be present. This is in particular the case when pySim-shell is used on a card that is not provisioned/initialized yet. In those cases we have to go the direct route and reset the card directly.
pySim-shell: add new commandline option "--skip-card-init"
by default pySim-shell does all kinds of probing and file selection on startup. This is to determine the card type and to find a suitable card profile. However, in case the card is non yet provisioned this probing may cause a error messages and even might upset the cards internal state. So let's have a commandline option thrugh which we can instruct pySim-shell to skip any initialization and to give us a prompt immediately, so that we can enter custom APDUs
pySim-shell_test/utils: treat cmd2 error "not a recognized command... as exception
When a pySim-shell command is not recognized, cmd2 prints "xyz is not a recognized command, alias, or macro." This string is a normal print out and not an exception, but during tests, it may point out a severe problem and therefore it should be tread like an exception.
Sphinx is complaining about a duplicate label "osmo-smdpp". Apparantly because we use this label twices as section headline. The subsection "osmo-smdpp" in "Running osmo-smdpp" talks about the commandline and the supplementary files that osmo-smdpp needs to run. Let's split the two topics into two different sections.
The _wrap_cmd_apdu methods for SCP02 and SCP03 are a bit hard to read. Let's refactor them so that it is easier to understand what happens. In particular that one can not have encryption (cenc) without signing (cmac)
pySim/transport add support for T=1 protocol and fix APDU/TPDU layer conflicts
ETSI TS 102 221, section 7.3 specifies that UICCs (and eUICCs) may support two different transport protocols: T=0 or T=1 or both. The spec also says that the terminal must support both protocols.
This patch adds the necessary functionality to support the T=1 protocol alongside the T=0 protocol. However, this also means that we have to sharpen the lines between APDUs and TPDUs.
As this patch also touches the low level interface to readers it was also manually tested with a classic serial reader. Calypso and AT command readers were not tested.
pySim-shell_test: add new testcase for card initialization
The card initialization normally takes place automatically. Nearly all testcases implicitly cover this code-path. However, it is also possible to skip the card initialization and do it at some later point. This is commonly the case for unprovisioned card that require some custom APDUs in a basic initialization step. When this step is done one would use the "equip" command to level up to the full featured mode. This patch adds a testcase for this scenario
With osmo-remsim and Android APDU proxy we have two powerful solutions to allow remote acces to UICC/eUICC cards. Let's add a section where we give a brief overview about those solutions, so that pySim-shell users get awre of them.
So far we only thought of default filling coming from a template. However, filling can happen from the Fcp, and we need to properly parse and [re-]encode that information.
Commit
34423337608c56db3c83cda0b0c372e38aa1c01e
by laforge
esim.saip: New methods for inserting ProfileElement into sequence
ProfileElements.insert_after_pe() is a convenience method to insert a new PE after an existing one in the sequence. This is a frequent task as there are strict ordering requirements in the SAIP format.
Commit
0516e4c47ae07ad35dfad5eb5aed1fd26f43602b
by laforge
esim.saip.File: Re-compute file_size when changing body
If the API user modifies the size of the body, we need to check if we need to re-compute the file_size attribute which is later encoded into the fileDescriptor. The size obviously must be large enough to fit the body. Let's do this implicitly by introducing a setter for File.body
Commit
0f1ffd20efe9a3b34ed5288bd725ec83beeac555
by laforge
esim.saip.File: Proper ARR conversion of template (into) to file (bytes)
The encoding of the access rule reference is different in FileTemplate vs File, let's make sure we properly convert it when instantiating a File from a FileTemplate.
Commit
9ac4ff3229edb34e9956f4da84ece64a4a5d70ba
by laforge
esim.saip.File: Suppress encoding attributes that are like template
The point of the SAIP template mechanism is to reduce the size of the encoded profile. Therefore, our encoder in the to_fileDescriptor() method should suppress generating attributes if their value is identical to that of the template (if any).
So far we mainly created File() instances when parsing existing profiles. However, sometimes we want to programmatically create Files and we should offer a convenience helper to do so, rather than asking API users to worry about low-level details.
Commit
0bb8b44ea828de58dfb25ec6325197b3b46654d4
by laforge
esim.saip.ProfileElementUSIM: Fix IMSI decode if [only] template based
In case the fileDescriptor of EF.IMSI is purely template based and only the file content is given in the actual profile, we must pass a template reference to the File() constructor before we can read the IMSI.
This fixes the following exception for some profiles: ValueError: File(ef-imsi): No fileDescriptor found in tuple, and none set by template before
Commit
1be2e9b7132c529f73b23d78a9b2aba262bb17b8
by laforge
contrib/suci-keytool.py: Convenience tool for SUCI key generation
This adds a small utility program that can be used for generating keys used for SUCI in 5G SA networks, as well as for dumping them in a format that's compatible with what is needed on the USIM.
Commit
2debf5dc4be459ae12e173906e01ca033a5ea79c
by laforge
docs/shell: Fix documentation for eUICC ISD-R specific commands
Back in January 2024 in change 7ba09f9392c8023842a7b5576936cb21ff85c6c0 we migrate dthe commands from 'class ADF_ISDR' to CardApplicationISDR without updating the sphinx-argparse references in the documentation.
Let's fix that, making the syntax reference for those commands re-appear in the documentation.
the testcase EF_ePDGSelection has a wrong testvector in the plmn field. This test vector is accepted because there is a complementary error in pyosmocom. However, the root problem got fixed (see depends), which means that the test vector of EF_ePDGSelection now needs to be updated.
When the equip method is running, all kinds of states in pySim-shell are reset. To be sure that the card state is also reset (normally this is the case because usually init_card is called before equip), we should send an explicit reset to the card as well.
Commit
16920aeacd467b80e39a3dd90520de69754fc005
by laforge
README.md update / re-wording
Let's give a better description of what the project is all about, and differentiate reading/exploring any SIM from writing/updating a special programmable one where you know the ADM credentials.
there are multiple references to a specification "SEID". As it seems this is a reference to the GlobalPlatform "Secure Element Access Control" spec, which has the document reference "GPD_SPE_013". Let's use "GPD_SPE_013" to referene the spec.
GPD_SPE_013 Table 6-3 defines two types of AID-REF-DO objects (both are fully independed TLV IEs with the same name). The version with tag '4F' identifies an SE application. It may contain an AID prefix or even be of length 0 in case the rule should apply to all SE applications. Then there is the version with tag 'C0', which must always have length 0 and serves a flag to apply the rule to the implicitly selected SE application. Technically both are completely different things, so we must also treat them separately in the pySim-shell code.
javacard: add parser for JAVA-card CAP file format
To install JAVA-card applets we need to be able to extract the executeable loadfile and the AIDs of the applet and the loadfile. This patch adds the parser and related unittests.
Commit
14d6e68ff796320a76bcf5a66559891c0b8202be
by laforge
cards: Avoid exception seen with (some) GSM-R SIM cards
Some old cards are classic SIM and not based on UICCs. Such cards do not offer the capability of selecting applications. Let's avoid running into an exception by providing dummy methods that simply fail for each AID selection.
global_platform: fix usage of the Key Version Number (kvn)
The kvn parameter is used to select a keyset when establishin a secure channel. At the moment this is a mandatory parameter and it must be within a certain range.
However GPC_SPE_034 explicitly defines a reserved kvn value 0, that always refers to the first available key. That effectively makes it an optional parameter and the commandline interface should have the --key-ver parameter as an optional parameter.
The ranges also have to be extended to allow 0 as kvn value. We also have to put a range to support the sysmoUSIM-SJS1, which uses kvn value 1, which is a non standard value.
Installing JAVA-card applets from a CAP file is a multi step process, which is difficult when done manually. Fortunately it is easy to automate the process, so let's add a dedicated command for that.
ATR: use lowercase hex strings without spaces as ATR constants
The ATR constants are the only hex string constants where the hex bytes digits are separated with spaces. Also the hex digits are in lowercase. Let's use a lowercase string without spaces here like we do in many other code locations.
pySim/transport: add abstract get_atr method to LinkBase
The implementations that inheret from the LinkBase class are expected to implement a get_atr method. This method is mandatory, since it is one of the most basic functionalities of pySim to display an ATR. Also the ATR is sometimes needed to distinguish between different card models.
The modem_atcmd and calypso implementation completely lack the get_atr method. Apparantly it is not possible to get an ATR in those environments, so lets add a dummy method there.
Before this patch, that would result first in package pySim.esim.saip being unknown (not installed at all), and when that is added to setup.py, in this error:
Traceback (most recent call last): File "/home/moi/osmo-dev/src/pysim/tests/unittests/./test_esim_saip.py", line 23, in <module> from pySim.esim.saip import * File "/home/moi/s/esim/sysmo_esim_mgr/venv/lib/python3.13/site-packages/pySim/esim/saip/__init__.py", line 41, in <module> asn1 = compile_asn1_subdir('saip') File "/home/moi/s/esim/sysmo_esim_mgr/venv/lib/python3.13/site-packages/pySim/esim/__init__.py", line 56, in compile_asn1_subdir for i in resources.files('pySim.esim').joinpath('asn1').joinpath(subdir_name).iterdir(): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^ File "/usr/lib/python3.13/pathlib/_local.py", line 577, in iterdir with os.scandir(root_dir) as scandir_it: ~~~~~~~~~~^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory: '/home/moi/s/esim/sysmo_esim_mgr/venv/lib/python3.13/site-packages/pySim/esim/asn1/saip'
After this patch, the test completes successfully.
...... ---------------------------------------------------------------------- Ran 6 tests in 0.067s
OK
Related: sysmocom's eSIM manager product that is currently in development needs to fully use pySim.esim.saip, ideally from a regular 'pip install', and not from using the pySim source tree directly.
pySim-shell: obey quit command in startup commands+scripts
Startup scripts are executed using the cmd2 provided onecmd_plus_hooks method. This method can run arbitrary commands, which also includes the command "run_scrit" that we use to execute startup scripts.
When a script executes a quit command, or when someone issues a quit command using the --execute-command or the command argument, then this commands is executed. However a quit command won't actually quit the process. All it does is to change the return code of app.onecmd_plus_hooks (see [1]). So we must evaluate the return code and take care of the quitting ourselves.
Commit
15df7cbf884f5db55c274a0951b577ce071ec7c2
by Neels Hofmeyr
add PEM cert as used in docs/osmo-smdpp.rst
Add PEM version of smdpp-data/certs/DPtls/CERT_S_SM_DP_TLS_NIST.der
A CERT_S_SM_DP_TLS_NIST.pem file is referenced in docs/osmo-smdpp.rst -- nginx apparently cannot use DER certs, so it is convenient for beginners if the example from the docs just works without having to know that:
The added file was produced using
openssl x509 -inform DER -in CERT_S_SM_DP_TLS_NIST.der -outform PEM -out CERT_S_SM_DP_TLS_NIST.pem
Commit
74be2e202fd8c503eb00a870519fdf5c14b39fb7
by laforge
filesystem: do not decode short TransRecEF records
A TransRecEF is based on a TransparentEF. This means that a TransRecEF is basically normal TransparentEF that holds a record oriented data structure. This also requires that the total length of the TransRecEF is a multiple of the record length of the data structure that is stored in it. When this is not the case, the last record will be cut short and the decoding will fail. We should guard against this case.
Commit
f57f6a95a5fae4246c0a65bf92ced951e803df07
by laforge
pySim/commands: Fix envelope command APDU case after T=1 support
When we merged I8b56d7804a2b4c392f43f8540e0b6e70001a8970 for T=1 support, the ENVELOPE C-APDU was not adjusted to reflect the correct case. ENVELOPE expects a response and hence needs a Le byte present.
This avoids below related message when performing e.g. OTA via SMS
Warning: received unexpected response data, incorrect APDU-case (3, should be 4, missing Le field?)!
saip-tool: allow removing of profile elements by type
At the moment it is only possible to remove profile elements by their identification number. However, there may be cases where we want to remove all profile elements of a certain type at once (e.g. when removing all applications).
saip-tool: add ProfileElement class for application PE
The application profile element has no ProfileElement class yet, so let's create a ProfileElementApplication class and move the existing extract-apps code into a method of ProfileElementApplication.
Commit
a2bfd397badd6bddff66d0a59a96e13cf4f4c9e1
by laforge
pySim-smpp2sim.py: Simulate SMSC+CN+RAN+UE for OTA testing
The pySim-smpp2sim.py program exposes two interfaces: * SMPP server-side port, so external programs can rx/tx SMS * APDU interface towards the SIM card
It therefore emulates the SMSC, Core Network, RAND and UE parts that would normally be encountered in an OTA setup.
Commit
1dea0f39dcf5abf15fd65bba824a7cf8fe1581d9
by laforge
saip-tool: add features to add, remove and inspect application PEs
The PE-Application object is used to provision JAVA-card applications into an eUICC during profile installation. Let's extend the SAIP-tool so that we are able to add, remove and inspect applications.
Commit
59faa02f9a746471bb8457788b1d6ffb02c3275c
by laforge
ara_m: add command to lock write access to the ARA-M rules.
Recent versions of the ARA-M applet from Bertrand Martel can lock the write access to ARA-M rules. Let's add a command for that and some documentation.
Commit
d838a95c2a60d63d49111083591fbe6c8c179b17
by laforge
edit_{binary,record}_decoded: Support hex-decode of bytes
We've created + used osmocom.utils.JsonEncoder as an encoder class for json.{dump,dumps} for quite some time. However, we missed to use this decoder class from the edit_{binary,record}_decoded commands in the pySim-shell VTY.
Commit
19f3759306abd1a835c79a77c0bd83490c3f9156
by laforge
osmo-smdpp: Renew SGP.26 TLS certificate for SM-DP+
The SGP.26 v3.0 certificate had expired on July 11, 2024. Let's replace it with a cert of 10 year validity period to facilitate uninterrupted testing with osmo-smdpp.
@@ -1,12 +1,12 @@ Certificate: Data: Version: 3 (0x2) - Serial Number: 9 (0x9) + Serial Number: 10 (0xa) Signature Algorithm: ecdsa-with-SHA256 Issuer: CN=Test CI, OU=TESTCERT, O=RSPTEST, C=IT Validity - Not Before: Jun 9 19:04:42 2023 GMT - Not After : Jul 11 19:04:42 2024 GMT + Not Before: Apr 23 15:23:05 2025 GMT + Not After : Apr 21 15:23:05 2035 GMT Subject: O=ACME, CN=testsmdpplus1.example.com Subject Public Key Info: Public Key Algorithm: id-ecPublicKey
Commit
949c2a2d579943f5286e1f4505be0835f149eab6
by laforge
Use osmocom.construct.{Bytes,GreedyBytes} for hexstring input support
The upstream construct.{Bytes,GreedyBytes} only support bytes/bytearray input data for the encoder, while the [newly-created] osmocom.construct.{Bytes,GreedyBytes} support alternatively hex-string input.
This is important in the context of encoding construct-based types from JSON, where our osmocom.utils.JsonEncoder will automatically convert any bytes to hex-string, while re-encoding those hex-strings will fail prior to this patch.
Commit
004b06eab1d89ba2b29d7de9b7747cc2cdd0c8fd
by Vadim Yanitskiy
jenkins.sh: workaround for 'usage: build.py' in docs
Recent versions of cmd2 have changed how the 'prog' attribute is automatically set for ArgumentParser instances. As a result, we are now seeing an unexpected 'build.py' artifact appearing in the generated documentation.
Let's use an older release of cmd2, which retains the old expected behavior. Use it specifically for building documentation.
Commit
c7c48718ba3637e29fc6a7af4e2e39ba0679bb8d
by laforge
Get rid of [now] superfluous HexAdapter
With the introduction of using osmocom.construct.{Bytes,GreedyBytes} in Change-Id I1c8df6350c68aa408ec96ff6cd1e405ceb1a4fbb we don't have a need for wrapping each instance of Bytes or GreedyBytes into a HexAdapter anymore. The osmocom.construct.{Bytes,GreedyBytes} will automatically perform the related hex-string-to-bytes conversion if needed - and during printing we have osmocom.utils.JsonEncoder that makes sure to convert any bytes type to a hex-string.
Commit
9572cbdb6132984c24dff1af0ca6bd5321b88380
by benispeter
smdpp: update certs
TLS will expire again: $ find . -iname "CERT*NIST*der" | xargs -ti openssl x509 -in {} -inform DER -noout -checkend $((24*3600*90)) ... openssl x509 -in ./smdpp-data/generated/DPtls/CERT_S_SM_DP_TLS_NIST.der -inform DER -noout -checkend 7776000 Certificate will expire ...
Grabbed from SGP.26_v1.5_Certificates_18_07_2024.zip available at https://www.gsma.com/solutions-and-impact/technologies/esim/gsma_resources/sgp-26-test-certificate-definition-v1-5/
Commit
ccefc98160303b149d8ef78ec55ecd04430a8384
by ewild
smdpp: add proper tls support, cert generation FOR TESTING
If TLS is enabled (default) it will automagically generate missing pem files + dh params.
A faithful reproduction of the certs found in SGP.26_v1.5_Certificates_18_07_2024.zip available at https://www.gsma.com/solutions-and-impact/technologies/esim/gsma_resources/sgp-26-test-certificate-definition-v1-5/ can be generated by running contrib/generate_certs.py. This allows adjusting the expiry dates, CA flag, and other parameters FOR TESTING. Certs can be used by the smdpp by running $ python -u osmo-smdpp.py -c generated
Commit
b4a12ecc1402f7a0975d32abb87477fe8ab6a0ee
by benispeter
smdp: update tls certs
Old expired today, new from https://www.gsma.com/solutions-and-impact/technologies/esim/wp-content/uploads/2021/07/SGP.26_v1.5-17-July-2025_files_v3.zip
Commit
10fe0e3aaeed857744819f487d1be7fbe270faf8
by Oliver Smith
docs: fix authors line exceeding the page
Fix that the authors get cut off as they exceed the page in the PDF version. This can currently be seen here: https://downloads.osmocom.org/docs/pysim/master/osmopysim-usermanual.pdf