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.
Change-Id: I9c77e420c314f5e74458628dc4e767eab6d97123
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.
Change-Id: I1c8df6350c68aa408ec96ff6cd1e405ceb1a4fbb
Closes: OS#6774
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
Change-Id: I6f67186b9b1b9cc81bfb0699a9d3984d08be8821
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.
Change-Id: I158e028f9920d8085cd20ea022be2437c64ad700
Related: OS#6774
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.
Change-Id: Ie5bae9d823bca6f6c658bd455303f63bace2258c
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?)!
Change-Id: Ice12675e02aa5438cf9f069f8fcc296c64aabc5a
Related: OS#6367
type annotations claimed the return type was Hexstr, but in reality
it was a list of integers. Let's fix that.
Change-Id: I01b247dad40ec986cf199302f8e92d16848bd499
Closes: OS#6322
In this patch we add the commands "install_for_load" and "load".
Depends: pyosmocom.git I86df064fa41db85923eeb0d83cc399504fdd4488
Change-Id: I924aaeecbb3a72bdb65eefbff6135e4e9570579e
Related: OS#6679
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.
Change-Id: Ib3457496380c0c5096052ad7799970ee620dee33
Closes: OS#6691
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.
Change-Id: Ied2a9626594e9735d92d4eabe6c6b90f92aa2909
Back in January 2024 in change 7ba09f9392
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.
Change-Id: I1d7e2d1a5dfbdcc11b1fdb3e89845787f7cddbfc
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.
Change-Id: I9e92bbba7f700e160ea9c58da5f23fa4c31d40c6
Those programs have been around since 2021 but we never had any
documentation here. Let's fix that.
Change-Id: I7c471cac9500db063a0c8f5c5eb7b6861b3234ed
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
Change-Id: I14157a7b62ccd9b5b42de9b8060f2ebc5f91ebb3
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.
Change-Id: I0817819af40f3d0dc0c3d2b91039c5748dd31ee2
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).
Change-Id: I337ee6c7e882ec711bece17b7a0def9da36b0ad7
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.
Change-Id: Ibb8afb85cc0006bc5c59230ebf28b2c0c1a8a8ed
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
Change-Id: I1a908504b845b7c90f31294faf2a6e988bdd8049
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.
Change-Id: I4424926127b4867931c2157e9340bacd2682ff0c
When generating the file content (body), we need to proceed in the
following order:
1a) If FCP contains fillPattern/repeatPattern, compute file content from those
1b) If FCP doesn't contain fillPattern/repeatPattern but template
exists, compute file content from template
2) Apply any fillFileConten / fillFileOffset from the SAIP File on top
of the above
Change-Id: I822bb5fbec11a3be35910a496af7168458fd949c
Closes: OS#6642
If we know the efFileSize and record_len, but Fcp doesn't contain
the number of records, we can simply compute it.
Change-Id: I0cc8e7241e37ee23df00c2622422904e7ccdca77
There's a second flag hidden in the TS 102 222 "Special File
Information"; let's parse + re-encode it properly.
Change-Id: I7644d265f746c662b64f7156b3be08a01e3a97aa
Related: OS#6643
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.
Change-Id: Iff339cbe841112a01c9c617f43b0e69df2521b51
Related: OS#6643
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.
Change-Id: I16797ca58c3ad6ebaf588d04fec011a0cbcfcef3
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.
Example:
./pySim-shell.py -p0 -e 'select ADF.USIM/EF.IMSI' -e 'read_binary_decoded'
Change-Id: I74004f46105553f077c039ca0f86f75afccc7342
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.
Change-Id: I01687bb54e65bf5cc318745df588c3d6ea14eb83
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.
Change-Id: I3b6c44d2f5cce2513c3ec8a3ce939a242f3e4901
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.
Change-Id: Ia7c049b31cb1c5c5bb682406d9dd7a73bcd43185
The M2M eUICC are completely different from the consumer/IoT eUICC.
Obtaining the EID works via GET DATA in the ECASD. Let's add support
for that.
Change-Id: I6cca6f75d268229244c90b3f1f88e26c89a2b4e0
Any program using argparse_add_reader_args() will get a new
long-opt '--apdu-trace' which enables a raw APDU trace to the console.
Change-Id: I4bc3d2e023ba360f07f024d7b661a93322f87530
The code had two problems:
* the RESET was only performed in the successful case, but not if
some exceptio was raised
* the RESET was a low-level reset bypassing the RuntimeState,
so the lchan.selected_file was stale afterwards
Fixes: Change-Id Idc2ea1d9263f39b3dff403e1535a5e6c4e88b26f
Change-Id: Ib23d3d5b58b456a25157a622c1010c81cd8b2213
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.
Let's change that.
Change-Id: Ic772b3383533f845689ac97ad03fcf67cf59c208
When constructing a ProfileElmentGFM from scratch, initialize the
decoded['fileManagementCMD'], as it is a mandatory member during
ASN.1 encode.
Change-Id: Iaae99348d36b7f0c739daf039d6ea2305b7ca9db
The choice member is called df-5gprose but the header is called
'df-5g-prose-header' (note the '-' between '5g' and 'prose'). WTF.
Change-Id: I86004ac2e18a187c26c5e470344908512d21fb9e
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...
Change-Id: If5e670441f03a47fa34e97a326909b24927c12f7
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.
Change-Id: I4b63e45bcb0c9ba2424dacf85e0222aee735f411
This is the only way we can make sure pylint has all required
information about imports from packages we depend upon.
Change-Id: I29582aa3d7f9ace9ce832d5b907420aaf14881fb
************* Module pySim.esim.es2p
pySim/esim/es2p.py:107:19: E1101: Class 'datetime' has no 'toisoformat' member (no-member)
Change-Id: Ib762792d595048bf6d7d6f5acbe2715f137ae5bb
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.
Change-Id: I2caadc24b1087855f23f3c57cdf8dabbf81757c0
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.
Change-Id: I0e6c97721fb1cfc6b5c21595d85bd374d485b573
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.
Change-Id: I24b692e47e4dd0afb5a17b04d5e0251dded3d611
Having AKA specific code in the generic ProfileElement base class dated
back to when we didn't have a ProfileElementAKA subclass.
Change-Id: Icd332183758b8ef20a77507b728f5e455698def0
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.
Change-Id: I3ba092e0893f53a18264dff5fa37b12ccd9bd47e
So far the prefix_match() required a string argument; let's also
permit another OID object to be passed; we internally convert that
to string.
Change-Id: I0feb7782d1813cc46ec78f170eb0fce804aebe3a
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.
Change-Id: Ia7e9375b3258d1fbfdc892cefba3e3bbe841c550
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.
Change-Id: If0076cc6dd35a818c08309885f6ef1c1704052c6
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.
Change-Id: Ieab4835cd21008b289713784c0eb7170af2ccfb9
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.
Change-Id: I73bd1ab3780e475c96a10cd5dbdd45b829c67335
Closes: OS#6530
This method can be used to expand the default value pattern of the
file system template for the file to the specified (record, file) length.
Change-Id: Id3eb16910c0bdfa572294e14ca1cd44ca95ca69f
The default value must contain '...' to indicate a variable-length
default value section, not '..'
Change-Id: I8d78278065c145b86460acf8eb723babe777c4f6
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.
Change-Id: I3a894c72c22e42bd2067e067be80a67197ad1bf2
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.
Change-Id: Ie145ba159081daf8fbfa544f6d4248f05b7eea96
We previously only permitted this for transparent files (TR), but
file size can of course also be specified for BER-TLV files.
Change-Id: Ie007cf2ccde0a17d0fb853a96b833f064ae52c59
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
Change-Id: I6eaa5b579f02c7d75f443ee2b2cc8ae0ba13f2fe
Closes: OS#6485
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().
Change-Id: Ic1f9db45db75b887227c2e20785198814cbab0f5
Fixes: OS#6453
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.
Change-Id: I3aaec40eb665d6254be7b103444c04ff48aac36d