56 Commits

Author SHA1 Message Date
Philipp Maier
289fd28091 serial: do not try to close non existing serial connection
The SerialSimLink only has an _sl member if serial initalization was
successfull. If we close a serial connection, check if we even have the
_sl member. Otherwise move on silently.

Change-Id: Ic3f3f5e50d780f424da7d0be5733d7167bb7159c
2021-02-25 16:27:08 +01:00
Philipp Maier
92bdd5e901 serial: don't crash if the device does not exist
The most common reason for pySim to crash is when it is executed without
commandline parameters. Then pySim will expect a serial reader on
/dev/ttyUSB0 since this is the default. Lets check if /dev/ttyUSB0 even
exists before trying to open it.

Change-Id: I7545c728b531e9a796eee8f80f0b08d4097f8399
2021-02-25 16:27:08 +01:00
Philipp Maier
c8caec2933 utils: catch exceptions during reader initalitation
Failed reader initializations happen frome time to time, mostly because
of messed up commandline arguments. This results in ugly crashes very
often. Lets control this a bit by catching the exception string and
print it.

Change-Id: I313017355da01bbef7c3d3f1899555aadb509319
2021-02-25 15:16:07 +01:00
herlesupreeth
bdf3d3597b utils.py: Fix for parsing MNC
This commit fixes the incorrect parsing of MNC from PLMN.
Previously its was parsing PLMN string 130062 as MCC 310 MNC 260,
whereas it should be MCC 310 MNC 026.

(The SIM was programmed with MCC 310 and MNC 026)

Change-Id: I799469206f87e930d8888367890babcb8ebe23a9
2021-02-11 07:02:50 +01:00
herlesupreeth
cebf8b198b pySim-read.py: Add support for reading USIM+ISIM data from third-party UICC
Change-Id: Id8b95630e90cb5833482da2690e423e7adefb95b
2021-01-21 06:13:03 +01:00
Joachim Steiger
06a1256b67 Readme.md: update debian deps, add python3-yaml
Change-Id: Ic0d53ec3f312afee9d28f2f63d35e5c56dfd4686
2021-01-20 19:04:41 +01:00
Supreeth Herle
be3b64167a pySim-read.py: Enable reading of UICC IARI from ISIM
Change-Id: Iba222421f2fcc2b9b12605608bf640f7627904d0
2021-01-05 15:59:38 +01:00
Supreeth Herle
a97944b6ca sysmoISIM-SJA2: Enable programming of EF.ACC
Change-Id: If318117a2339399191dfc3fcec856d9247a034fb
2021-01-05 15:59:38 +01:00
Supreeth Herle
c60192375e sysmoISIM-SJA2: Enable programming of EF.MSISDN
Change-Id: I8ed27142009a50a1cc31a9f2e0e854a53add6e89
2021-01-05 15:59:37 +01:00
Supreeth Herle
be7007e1d9 sysmoISIM-SJA2: Add support for programming IMS public user identity
This EF contains one or more records, with each record able
to hold a public SIP Identity (SIP URI) of the user. EF.IMPU consist of URI TLV data
object values see IETF RFC 3261. The URI shall be encoded to an octet string according
to UTF-8 encoding rules as specified in IETF RFC 3629

./pySim-prog.py -p 0 -x 001 -y 01 -s 8988211900000000004 -i 001011234567895 -k 8baf473f2f8fd09487cccbd7097c6862 --op 11111111111111111111111111111111 -o 8E27B6AF0E692E750F32667A3B14605D -a 85524953 -n isim.test --msisdn 0598765432100 --epdgid epdg.epc.mnc001.mcc001.pub.3gppnetwork.org --pcscf pcscf.ims.testop.org --ims-hdomain ims.testop.org --impi 1234567895@ims.testop.org --impu sip:5987654321@ims.testop.org

Change-Id: If10bc2e50eca390b81755b5cc7211e695233612d
2021-01-05 11:46:41 +01:00
Supreeth Herle
a5bd9684d3 sysmoISIM-SJA2: Add support for programming IMS private user identity
This EF contains the private user identity of the user. EF.IMPI consist of
NAI TLV data object values see IETF RFC 2486. The NAI shall be encoded to
an octet string according to UTF-8 encoding rules as specified in IETF RFC 3629

./pySim-prog.py -p 0 -x 001 -y 01 -s 8988211900000000004 -i 001011234567895 -k 8baf473f2f8fd09487cccbd7097c6862 --op 11111111111111111111111111111111 -o 8E27B6AF0E692E750F32667A3B14605D -a 85524953 -n isim.test --msisdn 0598765432100 --epdgid epdg.epc.mnc001.mcc001.pub.3gppnetwork.org --pcscf pcscf.ims.testop.org --ims-hdomain ims.testop.org --impi 1234567895@ims.testop.org

Change-Id: Ic1ccf99b5aa45297ef1e43a43373df603f756379
2021-01-05 11:46:41 +01:00
Supreeth Herle
0c02d8a57b pySim-read.py: Enable reading of EF.IMPU from ISIM
IMS public user identity (IMPU)
As per TS1.103, this EF contains one or more records, with each record able
to hold a public SIP Identity (SIP URI) of the user. EF.IMPI consist of URI TLV data
object values see IETF RFC 3261. The URI shall be encoded to an octet string according
to UTF-8 encoding rules as specified in IETF RFC 3629

Reading of EF.IMPU is achieved by first selecting the ISIM application using its AID.
This is followed by selecting EF.IMPU with File ID - 6f04 in ADF.ISIM

Change-Id: Icf78a564aeaf4254658d3b018ff57dfc4b987e6f
2021-01-05 11:46:41 +01:00
Supreeth Herle
3f67f9c1d3 pySim-read.py: Enable reading of EF.IMPI from ISIM
IMS private user identity (IMPI)
As per TS1.103 version 14.2.0, this EF contains the private user identity of the user.
EF.IMPI consist of NAI TLV Data object.The NAI shall be encoded to an octet string
according to UTF-8 encoding rules as specified in IETF RFC 3629.

Reading of EF.IMPI is achieved by first selecting the ISIM application using its AID.
This is followed by selecting EF.IMPI with File ID - 6f02 in ADF.ISIM

Change-Id: I8d8e76e3f6b9ca7a0be262fee99cd5a397edbefa
2021-01-05 11:46:41 +01:00
Supreeth Herle
28484d03e3 Update ISIM IST table as per the 3GPP TS 31.103 specification V15.6.0
Change-Id: I8f6a96721beb9621ac453715cf2d0303989cfe85
2021-01-05 11:46:41 +01:00
herlesupreeth
1279085f7e sysmoISIM-SJA2: Add support for programming IPv4 address for PCSCF
This commit allows programming of IPv4 or FQDN in EF.PCSCF

Example:

./pySim-prog.py -p 0 -x 001 -y 01 -s 8988211900000000004 -i 001011234567895 -k 8baf473f2f8fd09487cccbd7097c6862 --op 11111111111111111111111111111111 -o 8E27B6AF0E692E750F32667A3B14605D -a 85524953 -n isim.test --msisdn 0598765432100 --epdgid 172.24.15.20 --pcscf 99.100.80.102 --ims-hdomain testims.org

Change-Id: I247a5413e9e5fef6b9d7b6cb8442313e72f9156a
2021-01-05 11:46:41 +01:00
Supreeth Herle
c491dc019f sysmoISIM-SJA2: Add support for programming IPv4 address for Home ePDG Identifier
This commit allows programming of IPv4 or FQDN in EF.ePDGId

Example:

./pySim-prog.py -p 0 -x 001 -y 01 -s 8988211900000000004 -i 001011234567895 -k 8baf473f2f8fd09487cccbd7097c6862 --op 11111111111111111111111111111111 -o 8E27B6AF0E692E750F32667A3B14605D -a 85524953 -n isim.test --msisdn 0598765432100 --epdgid 172.24.15.20 --pcscf pcscf.testims.org --ims-hdomain testims.org

Change-Id: I10a708d3e0c3ae398c942e3529e364dfe4bb23e7
2021-01-05 11:46:41 +01:00
Supreeth Herle
43fd03b627 utils.py: Support IPv4 decoding for Address TLV object present in EF.ePDGId and EF.ePDGIdEm
Change-Id: I96c30c1fcc03e50c55e9db7e6a18297a3b1d889d
2021-01-05 11:46:41 +01:00
Supreeth Herle
654eca72c9 utils.py: Support IPv4 encoding for Address TLV object present in EF.ePDGId and EF.ePDGIdEm
Change-Id: Id46a44257d09c98ad5e0b7558e25e2bc52b23978
2021-01-05 11:46:41 +01:00
Supreeth Herle
4779034f9e sysmoISIM-SJA2: Fill unused bytes of Home ePDGId with 'f'
Change-Id: Ia0464f230afcb0f37465d3ed0dfd8f417b53b0c3
2021-01-05 11:46:41 +01:00
Supreeth Herle
79f43dda3d sysmoISIM-SJA2: Add support for programming IMS Home Network Domain Name
As per 3GPP TS 31.103, this EF (DOMAIN) can found under ADF.ISIM at File Id 6f03.

The Home Network Domain Name, i.e. FQDN shall be encoded to an octet string
according to UTF-8 encoding rules as specified in IETF RFC 3629 [27].
The tag value of the Home Network Domain Name TLV data object shall be '80'.

Example:

./pySim-prog.py -p 0 -x 001 -y 01 -s 8988211900000000004 -i 001011234567895 -k 8baf473f2f8fd09487cccbd7097c6862 --op 11111111111111111111111111111111 -o 8E27B6AF0E692E750F32667A3B14605D -a 85524953 -n isim.test --msisdn 0598765432100 --epdgid epdg.epc.mnc001.mcc001.pub.3gppnetwork.org --pcscf pcscf.testims.org --ims-hdomain testims.org

Change-Id: I3c823203aee88734ae423e4ad73da1027a4eaeed
2021-01-05 11:46:41 +01:00
Supreeth Herle
556b0fe262 utils.py: Add helper method to get type of address (FQDN, IPv4, IPv6)
The function takes address string as input, then validates it and returns the type.
Return: 0x00 (FQDN), 0x01 (IPv4), 0x02 (IPv6), None (Bad address format)

Change-Id: I0fabd4f17bbb11f6bb191c1a9e6276427f9d001f
2021-01-05 11:46:41 +01:00
Supreeth Herle
44e046240e sysmoISIM-SJA2: Disable Service 95, 99, 115 in EF.UST in case ISIM is present
As per TS 31.102 version 15.2.0 Release 15, section 4.2.8, EFUST (USIM Service Table),
Service n°95, n°99 and n°115 shall not be declared available if an ISIM application is present on the UICC.

Change-Id: Id9709746de99585ad31c4e9659323484fda87b14
2021-01-05 11:46:41 +01:00
Supreeth Herle
05b2807168 pySim-read.py: Enable reading of Home Network Domain Name from ISIM
As per TS1.103 version 14.2.0, this EF contains the home operator's network domain name.
The Home Network Domain Name, i.e. FQDN shall be encoded to an octet string
according to UTF-8 encoding rules as specified in IETF RFC 3629

Change-Id: Ia3c68c717d105e10d52a8e9d170480da2ad7d65a
2021-01-05 11:46:40 +01:00
Supreeth Herle
cf727f2733 sysmoISIM-SJA2: Add support for programming Proxy Call Session Control Function address
Example:

./pySim-prog.py -p 0 -x 001 -y 01 -s 8988211900000000004 -i 001011234567895 -k 8baf473f2f8fd09487cccbd7097c6862 --op 11111111111111111111111111111111 -o 8E27B6AF0E692E750F32667A3B14605D -a 85524953 -n isim.test --msisdn 0598765432100 --epdgid epdg.epc.mnc001.mcc001.pub.3gppnetwork.org --pcscf pcscf.testims.org

Change-Id: Ic654baa93e2ecb91ced596b49dde4c1f208ecda2
2021-01-05 10:44:12 +01:00
Supreeth Herle
5ad9aec98f pySim-read.py: Enabled reading P-CSCF address from ISIM
As per 3GPP TS 31.103 version 14.2.0 Release 14, this EF can found under ADF.ISIM at File Id 6f09.

This EF contains one or more Proxy Call Session Control Function addresses.
The first record in the EF shall be considered to be of the highest priority
If ISIM service n°1 and/or service n°5 is available, this file shall be present.

Change-Id: I7a701212c84d3dc5d4c8ccbcf638c97ceda33654
2021-01-05 10:06:19 +01:00
herlesupreeth
75c14c0cbd ts_31_103.py: Add ADF map for files at ISIM ADF
EF_ISIM_ADF_map introduced in this commit maps EF file names in ISIM ADF
to its repective Identifier and serves as a lookup table

Change-Id: I95c8691d9112541c2c0e01857b19681c00f322f2
2021-01-05 10:06:19 +01:00
herlesupreeth
b0c7d121d7 sysmoISIM-SJA2: Inherit ISIM Card class as SysmoISIMSJA2 UICC contains an ISIM
Change-Id: I87b318d2df491b9d3c90aad0c38be9bd41e6cf56
2021-01-05 10:06:19 +01:00
herlesupreeth
ecbada993d cards: Define ISIM Card class
This commit introduces a ISIM generic Card class which can hold
parameters/functions specific to ISIM application on UICC

Change-Id: I242e679ff2f8831175e76d2fcc5fb285d28bd890
2021-01-05 10:06:19 +01:00
Supreeth Herle
3b342c2f14 Re-purpose helper method to be used for parsing Address TLV Object in general
The Address TLV object is used in EF.P-CSCF Address, EF.ePDGId and EF.ePDGIdEm.
See 3GPP TS 31.102 version 13.4.0 Release 13, section 4.2.8, 4.2.102 and 4.2.104.

Address TLV Object format
Tag (1 Byte) - '80'
Length (1 Byte)
Address Type (1 Byte) - '00' (FQDN), '01' (IPv4), '02' (IPv6)
Address (Address Length Bytes)

Change-Id: Ifd8a240f6b5c7736e58a8151295c30ec5b32ed5f
2021-01-05 10:06:19 +01:00
Supreeth Herle
acc222f9f0 sysmoISIM-SJA2: Enable Service 106 and 107 after successfully programming EF.ePDGId and EF.ePDGSelection
Service 106 and 107 must be set available in order to ME to consider as supported in USIM:
1. ePDG configuration Information support
2. ePDG configuration Information configured

Change-Id: Ica067915b9d06ba67f53da7d628f8bacde1ab80e
2021-01-05 10:06:19 +01:00
Supreeth Herle
f964df4eb5 sysmoISIM-SJA2: Add support for programming EF.ePDGSelection (ePDG Selection Information)
If the EF.ePDGSelection is present, it is populated with a single entry with PLMN 1 set
to Home PLMN of USIM, ePDG FQDN format set to Operator Identifier FQDN and ePDG Priority value
set to 1.

Change-Id: I92f3f813afa41ae497ebc0dc2ca73da810f82364
2021-01-05 10:06:19 +01:00
herlesupreeth
3a261d31d5 utils.py: Bugfix for parsing non-programmed EFePDGSelection
Change-Id: I3a16af785d8ae9ea8730771367bba2d50690b414
2021-01-05 10:06:19 +01:00
Joachim Steiger
5e67d5b80a Readme.md: update apt-get invocation for python3 dep.
Change-Id: Icb09204d6bc0d89fa8b793ff6df773cdefc19c5b
2020-12-11 19:24:31 +01:00
Jeremy Herbert
3b00dbf0d2 make random seed function python3 compatible
Change-Id: Iea8c93c20abe080eeb18026faeeb2668664871bb
2020-10-26 18:55:25 +01:00
Supreeth Herle
95ec772b61 utils.py: Add helper method to encode ePDGSelection info TLV
Encodes ePDGSelection info TLV so it can be stored at EF.ePDGSelection or EF.ePDGSelectionEm.
See 3GPP TS 31.102 version 15.2.0 Release 15, section 4.2.104 and 4.2.106.

Take original hex string of EF.ePDGSelection or EF.ePDGSelectionEm, MCC,
MNC, ePDG priority for PLMN and ePDG FQDN Format to use for PLMNas input
and outputs the encoded hex string.

Change-Id: Ia7292d33783c770a3bb91b081c671af36bbb907f
2020-10-21 08:32:57 +02:00
Supreeth Herle
99d55552d5 pySim-read.py: Enable parsing of EF.ePDGSelection in USIM
As per TS 31.102, this EF can found under ADF.USIM at File Id 6ff4.
Also, if service n°106 and service n°107 are available, this file shall be present.

Change-Id: I98916e6f5c9791aff63c18a3b16bdfb8ae9b2d36
2020-10-21 08:32:55 +02:00
Supreeth Herle
95b4e8d4fa utils.py: Add helper method to parse ePDG Selection info TLV
ePDG selection information TLV data object is made of following elements:

ePDG Selection Information Tag '80' (1 Byte)
Length 5n Note
PLMN 1 (3 Bytes)
ePDG Priority (2 Bytes)
ePDG FQDN format '00' or '01' (1 Byte)
...

PLMN n
...

Note: The length is coded according to ISO/IEC 8825-1 [35]

Note 2: Inconsistency in spec: 3GPP TS 31.102 version 15.2.0 Release 15, 4.2.104

As per spec, Length field value is 5n, where n is number of PLMNs
But, each PLMN entry is made of PLMN (3 Bytes) + ePDG Priority (2 Bytes) + ePDG FQDN format (1 Byte)
Totalling to 6 Bytes, maybe Length should be 6n and not 5n

Change-Id: I0f9f38961a589e3f9a53d2288a3dc6fa71a4b1b0
2020-10-21 08:25:41 +02:00
Daniel Willmann
5d8cd9b378 Whitespace fixes
Change-Id: I595c70ca876d07277551d340c3c5df4d49b1928c
2020-10-19 11:01:49 +02:00
Daniel Willmann
dd014ea306 Lint fixes: false -> False, missing imports, Index list, not map iter
Change-Id: Iff4123a49c8dbcfc405612c0663d5c7d0f549748
2020-10-19 10:35:11 +02:00
Daniel Willmann
677d41bb41 Remove unnecessary semicolon
Change-Id: I9c5665cd2a45a0d06444349eaaeeb5b83a09ffc1
2020-10-19 10:34:31 +02:00
Daniel Willmann
de07b95f84 Fix invocation python2 -> python3
Change-Id: Ic78da9c03e99f59d142c93394051bbc2751f0205
2020-10-19 10:32:34 +02:00
herlesupreeth
4a3580b4c1 Move reading of USIM service table to generic USIM class
Change-Id: I537547f3bd01a547310358f8a8fceddcb4c79f37
2020-10-03 07:37:06 +00:00
herlesupreeth
f8232db327 Move reading of ePDG Id to generic USIM class
Change-Id: I716acb994430db3d4e56fea072f8dc2cebeaba84
2020-10-03 07:36:58 +00:00
herlesupreeth
5d0a30c19c Move programminig of ePDG Id to generic USIM class
Change-Id: I198d2d3303343b24ec92ba73cce21257213f6f89
2020-09-29 09:44:24 +02:00
herlesupreeth
3409ae7eea Remove redundant hexstr_to_fivebytearr() and hexstr_to_threebytearr() functions
These functions are replaced by a more generic function hexstr_to_Nbytearr().
And, all occurances of redundant functions are replaced by generic functions
so its safe to remove them.

Change-Id: I7848451b90b35dca29d29f630cdc5405b5e9c19b
2020-09-20 09:49:22 +00:00
herlesupreeth
45fa604834 Use generic function hexstr_to_Nbytearr to convert hex string to 3/5 Bytes array
Change-Id: I1165e4928d063667f0b4dfc3437c9278e7ec7450
2020-09-20 09:49:22 +00:00
Supreeth Herle
f394853533 utils.py: Add helper method to convert a hex string into array of N bytes string elements
Change-Id: I3af080726079729eae92af183de40dfc70c9390e
2020-09-20 09:49:22 +00:00
Supreeth Herle
d84daa12c2 utils.py: Add helper method to encode Service Table
This method helps in encoding of Service Tables in EF.SST, EF.UST, EF.EST, EF.IST.
Takes original hex string of EF.SST, EF.UST, EF.EST, EF.IST, Service number,
Service to be enabled or disable flag as input and outputs the modified Service Table.

Change-Id: I0c97317d5a17aa0df720659d021b5cbf7d30edcc
2020-09-20 09:49:22 +00:00
Vadim Yanitskiy
dfe3dbb117 pySim-read.py: decode contents of EF.AD (Administrative data)
Change-Id: I938667bdf99d238eefac205d6dd70db1d714d842
2020-09-20 06:58:36 +00:00
herlesupreeth
a562ea0351 Add new line
Change-Id: I15c22131cf1e8695b6fb29b12f240d72ac5a423b
2020-09-16 20:31:28 +02:00
Supreeth Herle
4d9e6beaed Update UST table as per the latest 3GPP TS 31.102 specification
Change-Id: I07e250f0ada325a23cd58a33f162b0faa01d272b
2020-09-16 20:31:26 +02:00
Supreeth Herle
8e0fccdbf3 sysmoISIM-SJA2: Add support for programming Home ePDG Identifier
Example:

./pySim-prog.py -p 0 -x 001 -y 01 -s 8988211900000000004 -i 001011234567895 \
	-k 8baf473f2f8fd09487cccbd7097c6862 --op 11111111111111111111111111111111 \
	-o 8E27B6AF0E692E750F32667A3B14605D -a 85524953 -n isim.test \
        --msisdn 0598765432100 --epdgid epdg.epc.mnc001.mcc001.pub.3gppnetwork.org

Note:

1. For Operator Identifier based ePDG FQDN must be in the format

epdg.epc.mnc<MNC>.mcc<MCC>.pub.3gppnetwork.org

2. For Tracking/Location Area Identity based ePDG FQDN must be in format

lac<LAC>.epdg.epc.mnc<MNC>.mcc<MCC>.pub.3gppnetwork.org

and

tac-lb<TAC-low-byte>.tac-hb<TAC-high-byte>.tac.epdg.epc.mnc<MNC>.mcc<MCC>.pub.3gppnetwork.org

and

3. For 5GS Tracking Area Identity based ePDG FQDN using a 3 octet TAC

tac-lb<TAC-low-byte>.tac-mb<TAC-middle-byte>.tac-hb<TAC-high-byte>.5gstac. epdg.epc.mnc<MNC>.mcc<MCC>.pub.3gppnetwork.org

Change-Id: Ia00bfea36c50b6a38a5387d2f8147f25c81b1de4
2020-09-15 15:56:31 +02:00
herlesupreeth
71e38482e1 Remove redundant function read_aid()
Change-Id: I46c4ac0b994db7fb5c3113175009175ec5c154e3
2020-09-15 15:56:31 +02:00
herlesupreeth
1a13c44200 Use the function select_adf_by_aid for selecting an AID
Basically, the idea is to read all the AIDs on the UICC once
rather than reading each time we want to select an ADF.

The function select_adf_by_aid select the ADF by its AID which
is already populated by read_aids() function

Change-Id: I5e0e87e9cf238922d60fda7a7836e65f91f2c233
2020-09-15 15:56:31 +02:00
Supreeth Herle
8016405994 cards.py: Populate AIDs present in SysmoISIMSJA2 UICC
Change-Id: I5f00aa9b03b41818aaa95291fe6c1e525bb0571f
2020-09-15 15:56:31 +02:00
Philipp Maier
0f247f8766 sysmo-isim-sja2: fix test expectations
The card in the automatic test setup had been replaced, change the ADM
pin and the ICCID so that it matches the new card. Also the new card
does not feature an MSISDN file and the formatting of the EHPLMN file
changed in the output of pySim-Read.py

Change-Id: I413f4b8267e01727c59ad135881b3a2ed723ff5f
2020-09-15 15:42:38 +02:00
21 changed files with 813 additions and 149 deletions

View File

@@ -40,8 +40,8 @@ pysim requires:
Example for Debian:
apt-get install python-pyscard python-serial python-pip
pip install pytlv
apt-get install python3-pyscard python3-serial python3-pip python3-yaml
pip3 install pytlv
Mailing List

View File

@@ -9,7 +9,7 @@ if [ ! -d "./pysim-testdata/" ] ; then
exit 1
fi
virtualenv -p python2 venv --system-site-packages
virtualenv -p python3 venv --system-site-packages
. venv/bin/activate
pip install pytlv
pip install pyyaml

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
#
# Utility to deal with sim cards and program the 'magic' ones easily
@@ -147,6 +147,24 @@ def parse_options():
parser.add_option("--acc", dest="acc",
help="Set ACC bits (Access Control Code). not all card types are supported",
)
parser.add_option("--epdgid", dest="epdgid",
help="Set Home Evolved Packet Data Gateway (ePDG) Identifier. (Only FQDN format supported)",
)
parser.add_option("--epdgSelection", dest="epdgSelection",
help="Set PLMN for ePDG Selection Information. (Only Operator Identifier FQDN format supported)",
)
parser.add_option("--pcscf", dest="pcscf",
help="Set Proxy Call Session Control Function (P-CSCF) Address. (Only FQDN format supported)",
)
parser.add_option("--ims-hdomain", dest="ims_hdomain",
help="Set IMS Home Network Domain Name in FQDN format",
)
parser.add_option("--impi", dest="impi",
help="Set IMS private user identity",
)
parser.add_option("--impu", dest="impu",
help="Set IMS public user identity",
)
parser.add_option("--read-imsi", dest="read_imsi", action="store_true",
help="Read the IMSI from the CARD", default=False
)
@@ -222,8 +240,9 @@ def parse_options():
def _digits(secret, usage, len, num):
s = hashlib.sha1(secret + usage + '%d' % num)
d = ''.join(['%02d'%ord(x) for x in s.digest()])
seed = secret + usage + '%d' % num
s = hashlib.sha1(seed.encode())
d = ''.join(['%02d' % x for x in s.digest()])
return d[0:len]
def _mcc_mnc_digits(mcc, mnc):
@@ -257,7 +276,7 @@ def _dbi_binary_quote(s):
m = sum_
e = i
if m == 0: # No overhead ? use this !
break;
break
# Generate output
out = []
@@ -300,7 +319,7 @@ def gen_parameters(opts):
if opts.name is not None:
if len(opts.name) > 16:
raise ValueError('Service Provider Name must max 16 characters!');
raise ValueError('Service Provider Name must max 16 characters!')
if opts.msisdn is not None:
msisdn = opts.msisdn
@@ -317,7 +336,7 @@ def gen_parameters(opts):
if opts.iccid is not None:
iccid = opts.iccid
if not _isnum(iccid, 19) and not _isnum(iccid, 20):
raise ValueError('ICCID must be 19 or 20 digits !');
raise ValueError('ICCID must be 19 or 20 digits !')
else:
if opts.num is None:
@@ -429,6 +448,15 @@ def gen_parameters(opts):
pin_adm = sanitize_pin_adm(opts)
# ePDG Selection Information
if opts.epdgSelection:
if len(opts.epdgSelection) < 5 or len(opts.epdgSelection) > 6:
raise ValueError('ePDG Selection Information is not valid')
epdg_mcc = opts.epdgSelection[:3]
epdg_mnc = opts.epdgSelection[3:]
if not epdg_mcc.isdigit() or not epdg_mnc.isdigit():
raise ValueError('PLMN for ePDG Selection must only contain decimal digits')
# Return that
return {
'name' : opts.name,
@@ -442,6 +470,12 @@ def gen_parameters(opts):
'acc' : acc,
'pin_adm' : pin_adm,
'msisdn' : opts.msisdn,
'epdgid' : opts.epdgid,
'epdgSelection' : opts.epdgSelection,
'pcscf' : opts.pcscf,
'ims_hdomain': opts.ims_hdomain,
'impi' : opts.impi,
'impu' : opts.impu,
}
@@ -488,15 +522,15 @@ def _read_params_csv(opts, iccid=None, imsi=None):
if opts.num is not None and opts.read_iccid is False and opts.read_imsi is False:
if opts.num == i:
f.close()
return row;
return row
i += 1
if row['iccid'] == iccid:
f.close()
return row;
return row
if row['imsi'] == imsi:
f.close()
return row;
return row
f.close()
return None
@@ -643,13 +677,13 @@ def process_card(opts, first, card_handler):
if opts.read_iccid:
if opts.dry_run:
# Connect transport
card_handler.get(false)
card_handler.get(False)
(res,_) = scc.read_binary(['3f00', '2fe2'], length=10)
iccid = dec_iccid(res)
elif opts.read_imsi:
if opts.dry_run:
# Connect transport
card_handler.get(false)
card_handler.get(False)
(res,_) = scc.read_binary(EF['IMSI'])
imsi = swap_nibbles(res)[3:]
else:
@@ -686,6 +720,8 @@ if __name__ == '__main__':
# Init card reader driver
sl = init_reader(opts)
if sl is None:
exit(1)
# Create command layer
scc = SimCardCommands(transport=sl)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
#
# Utility to display some informations about a SIM card
@@ -28,14 +28,15 @@ import os
import random
import re
import sys
from pySim.ts_51_011 import EF, DF, EF_SST_map
from pySim.ts_51_011 import EF, DF, EF_SST_map, EF_AD_mode_map
from pySim.ts_31_102 import EF_UST_map, EF_USIM_ADF_map
from pySim.ts_31_103 import EF_IST_map
from pySim.ts_31_103 import EF_IST_map, EF_ISIM_ADF_map
from pySim.commands import SimCardCommands
from pySim.cards import card_detect, Card
from pySim.cards import card_detect, Card, UsimCard, IsimCard
from pySim.utils import h2b, swap_nibbles, rpad, dec_imsi, dec_iccid, dec_msisdn
from pySim.utils import format_xplmn_w_act, dec_spn, dec_st, init_reader, dec_epdgid
from pySim.utils import format_xplmn_w_act, dec_spn, dec_st, init_reader, dec_addr_tlv
from pySim.utils import h2s, format_ePDGSelection
def parse_options():
@@ -81,6 +82,8 @@ if __name__ == '__main__':
# Init card reader driver
sl = init_reader(opts)
if sl is None:
exit(1)
# Create command layer
scc = SimCardCommands(transport=sl)
@@ -225,7 +228,15 @@ if __name__ == '__main__':
# EF.AD
(res, sw) = card.read_binary('AD')
if sw == '9000':
print("AD: %s" % (res,))
print("Administrative data: %s" % (res,))
if res[:2] in EF_AD_mode_map:
print("\tMS operation mode: %s" % (EF_AD_mode_map[res[:2]],))
else:
print("\tMS operation mode: (unknown 0x%s)" % (res[:2],))
if int(res[4:6], 16) & 0x01:
print("\tCiphering Indicator: enabled")
else:
print("\tCiphering Indicator: disabled")
else:
print("AD: Can't read, response code = %s" % (sw,))
@@ -241,33 +252,104 @@ if __name__ == '__main__':
# Check whether we have th AID of USIM, if so select it by its AID
# EF.UST - File Id in ADF USIM : 6f38
if '9000' == card.select_adf_by_aid():
# Select USIM profile
usim_card = UsimCard(scc)
# EF.EHPLMN
if card.file_exists(EF_USIM_ADF_map['EHPLMN']):
(res, sw) = card.read_ehplmn()
if usim_card.file_exists(EF_USIM_ADF_map['EHPLMN']):
(res, sw) = usim_card.read_ehplmn()
if sw == '9000':
print("EHPLMN:\n%s" % (res))
else:
print("EHPLMN: Can't read, response code = %s" % (sw,))
# EF.UST
(res, sw) = card.read_binary(EF_USIM_ADF_map['UST'])
if sw == '9000':
print("USIM Service Table: %s" % res)
# Print those which are available
print("%s" % dec_st(res, table="usim"))
else:
print("USIM Service Table: Can't read, response code = %s" % (sw,))
try:
if usim_card.file_exists(EF_USIM_ADF_map['UST']):
# res[0] - EF content of UST
# res[1] - Human readable format of services marked available in UST
(res, sw) = usim_card.read_ust()
if sw == '9000':
print("USIM Service Table: %s" % res[0])
print("%s" % res[1])
else:
print("USIM Service Table: Can't read, response code = %s" % (sw,))
except Exception as e:
print("USIM Service Table: Can't read file -- " + str(e))
#EF.ePDGId - Home ePDG Identifier
try:
(res, sw) = card.read_binary(EF_USIM_ADF_map['ePDGId'])
if sw == '9000':
content = dec_epdgid(res)
print("ePDGId:\n%s" % (len(content) and content or '\tNot available\n',))
else:
print("ePDGId: Can't read, response code = %s" % (sw,))
if usim_card.file_exists(EF_USIM_ADF_map['ePDGId']):
(res, sw) = usim_card.read_epdgid()
if sw == '9000':
print("ePDGId:\n%s" % (len(res) and res or '\tNot available\n',))
else:
print("ePDGId: Can't read, response code = %s" % (sw,))
except Exception as e:
print("ePDGId: Can't read file -- " + str(e))
#EF.ePDGSelection - ePDG Selection Information
try:
if usim_card.file_exists(EF_USIM_ADF_map['ePDGSelection']):
(res, sw) = usim_card.read_ePDGSelection()
if sw == '9000':
print("ePDGSelection:\n%s" % (res,))
else:
print("ePDGSelection: Can't read, response code = %s" % (sw,))
except Exception as e:
print("ePDGSelection: Can't read file -- " + str(e))
# Select ISIM application by its AID
if '9000' == card.select_adf_by_aid(adf="isim"):
# Select USIM profile
isim_card = IsimCard(scc)
#EF.P-CSCF - P-CSCF Address
try:
if isim_card.file_exists(EF_ISIM_ADF_map['PCSCF']):
res = isim_card.read_pcscf()
print("P-CSCF:\n%s" % (len(res) and res or '\tNot available\n',))
except Exception as e:
print("P-CSCF: Can't read file -- " + str(e))
# EF.DOMAIN - Home Network Domain Name e.g. ims.mncXXX.mccXXX.3gppnetwork.org
try:
if isim_card.file_exists(EF_ISIM_ADF_map['DOMAIN']):
(res, sw) = isim_card.read_domain()
if sw == '9000':
print("Home Network Domain Name: %s" % (len(res) and res or 'Not available',))
else:
print("Home Network Domain Name: Can't read, response code = %s" % (sw,))
except Exception as e:
print("Home Network Domain Name: Can't read file -- " + str(e))
# EF.IMPI - IMS private user identity
try:
if isim_card.file_exists(EF_ISIM_ADF_map['IMPI']):
(res, sw) = isim_card.read_impi()
if sw == '9000':
print("IMS private user identity: %s" % (len(res) and res or 'Not available',))
else:
print("IMS private user identity: Can't read, response code = %s" % (sw,))
except Exception as e:
print("IMS private user identity: Can't read file -- " + str(e))
# EF.IMPU - IMS public user identity
try:
if isim_card.file_exists(EF_ISIM_ADF_map['IMPU']):
res = isim_card.read_impu()
print("IMS public user identity:\n%s" % (len(res) and res or '\tNot available\n',))
except Exception as e:
print("IMS public user identity: Can't read file -- " + str(e))
# EF.UICCIARI - UICC IARI
try:
if isim_card.file_exists(EF_ISIM_ADF_map['UICCIARI']):
res = isim_card.read_iari()
print("UICC IARI:\n%s" % (len(res) and res or '\tNot available\n',))
except Exception as e:
print("UICC IARI: Can't read file -- " + str(e))
# Check whether we have th AID of ISIM, if so select it by its AID
# EF.IST - File Id in ADF ISIM : 6f07
if '9000' == card.select_adf_by_aid(adf="isim"):

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" pySim: card handler utilities

View File

@@ -25,8 +25,10 @@
from pySim.ts_51_011 import EF, DF
from pySim.ts_31_102 import EF_USIM_ADF_map
from pySim.ts_31_103 import EF_ISIM_ADF_map
from pySim.utils import *
from smartcard.util import toBytes
from pytlv.TLV import *
class Card(object):
@@ -204,30 +206,6 @@ class Card(object):
else:
return (None, sw)
# Read the (full) AID for either ISIM or USIM or ISIM application
def read_aid(self, isim = False):
# First (known) halves of the AID
aid_usim = "a0000000871002"
aid_isim = "a0000000871004"
# Select which one to look for
if isim:
aid = aid_isim
else:
aid = aid_usim
# Find out how many records the EF.DIR has, then go through
# all records and try to find the AID we are looking for
aid_record_count = self._scc.record_count(['2F00'])
for i in range(0, aid_record_count):
record = self._scc.read_record(['2F00'], i + 1)
if aid in record[0]:
aid_len = int(record[0][6:8], 16)
return record[0][8:8 + aid_len * 2]
return None
# Fetch all the AIDs present on UICC
def read_aids(self):
try:
@@ -288,7 +266,177 @@ class UsimCard(Card):
data, sw = self._scc.update_binary(EF_USIM_ADF_map['EHPLMN'], ehplmn)
return sw
def read_epdgid(self):
(res, sw) = self._scc.read_binary(EF_USIM_ADF_map['ePDGId'])
if sw == '9000':
return (dec_addr_tlv(res), sw)
else:
return (None, sw)
def update_epdgid(self, epdgid):
size = self._scc.binary_size(EF_USIM_ADF_map['ePDGId']) * 2
if len(epdgid) > 0:
addr_type = get_addr_type(epdgid)
if addr_type == None:
raise ValueError("Unknown ePDG Id address type or invalid address provided")
epdgid_tlv = rpad(enc_addr_tlv(epdgid, ('%02x' % addr_type)), size)
else:
epdgid_tlv = rpad('ff', size)
data, sw = self._scc.update_binary(
EF_USIM_ADF_map['ePDGId'], epdgid_tlv)
return sw
def read_ePDGSelection(self):
(res, sw) = self._scc.read_binary(EF_USIM_ADF_map['ePDGSelection'])
if sw == '9000':
return (format_ePDGSelection(res), sw)
else:
return (None, sw)
def update_ePDGSelection(self, mcc, mnc):
(res, sw) = self._scc.read_binary(EF_USIM_ADF_map['ePDGSelection'], length=None, offset=0)
if sw == '9000' and (len(mcc) == 0 or len(mnc) == 0):
# Reset contents
# 80 - Tag value
(res, sw) = self._scc.update_binary(EF_USIM_ADF_map['ePDGSelection'], rpad('', len(res)))
elif sw == '9000':
(res, sw) = self._scc.update_binary(EF_USIM_ADF_map['ePDGSelection'], enc_ePDGSelection(res, mcc, mnc))
return sw
def read_ust(self):
(res, sw) = self._scc.read_binary(EF_USIM_ADF_map['UST'])
if sw == '9000':
# Print those which are available
return ([res, dec_st(res, table="usim")], sw)
else:
return ([None, None], sw)
def update_ust(self, service, bit=1):
(res, sw) = self._scc.read_binary(EF_USIM_ADF_map['UST'])
if sw == '9000':
content = enc_st(res, service, bit)
(res, sw) = self._scc.update_binary(EF_USIM_ADF_map['UST'], content)
return sw
class IsimCard(Card):
def __init__(self, ssc):
super(IsimCard, self).__init__(ssc)
def read_pcscf(self):
rec_cnt = self._scc.record_count(EF_ISIM_ADF_map['PCSCF'])
pcscf_recs = ""
for i in range(0, rec_cnt):
(res, sw) = self._scc.read_record(EF_ISIM_ADF_map['PCSCF'], i + 1)
if sw == '9000':
content = dec_addr_tlv(res)
pcscf_recs += "%s" % (len(content) and content or '\tNot available\n')
else:
pcscf_recs += "\tP-CSCF: Can't read, response code = %s\n" % (sw)
return pcscf_recs
def update_pcscf(self, pcscf):
if len(pcscf) > 0:
addr_type = get_addr_type(pcscf)
if addr_type == None:
raise ValueError("Unknown PCSCF address type or invalid address provided")
content = enc_addr_tlv(pcscf, ('%02x' % addr_type))
else:
# Just the tag value
content = '80'
rec_size_bytes = self._scc.record_size(EF_ISIM_ADF_map['PCSCF'])
pcscf_tlv = rpad(content, rec_size_bytes*2)
data, sw = self._scc.update_record(EF_ISIM_ADF_map['PCSCF'], 1, pcscf_tlv)
return sw
def read_domain(self):
(res, sw) = self._scc.read_binary(EF_ISIM_ADF_map['DOMAIN'])
if sw == '9000':
# Skip the inital tag value ('80') byte and get length of contents
length = int(res[2:4], 16)
content = h2s(res[4:4+(length*2)])
return (content, sw)
else:
return (None, sw)
def update_domain(self, domain=None, mcc=None, mnc=None):
hex_str = ""
if domain:
hex_str = s2h(domain)
elif mcc and mnc:
# MCC and MNC always has 3 digits in domain form
plmn_str = 'mnc' + lpad(mnc, 3, "0") + '.mcc' + lpad(mcc, 3, "0")
hex_str = s2h('ims.' + plmn_str + '.3gppnetwork.org')
# Build TLV
tlv = TLV(['80'])
content = tlv.build({'80': hex_str})
bin_size_bytes = self._scc.binary_size(EF_ISIM_ADF_map['DOMAIN'])
data, sw = self._scc.update_binary(EF_ISIM_ADF_map['DOMAIN'], rpad(content, bin_size_bytes*2))
return sw
def read_impi(self):
(res, sw) = self._scc.read_binary(EF_ISIM_ADF_map['IMPI'])
if sw == '9000':
# Skip the inital tag value ('80') byte and get length of contents
length = int(res[2:4], 16)
content = h2s(res[4:4+(length*2)])
return (content, sw)
else:
return (None, sw)
def update_impi(self, impi=None):
hex_str = ""
if impi:
hex_str = s2h(impi)
# Build TLV
tlv = TLV(['80'])
content = tlv.build({'80': hex_str})
bin_size_bytes = self._scc.binary_size(EF_ISIM_ADF_map['IMPI'])
data, sw = self._scc.update_binary(EF_ISIM_ADF_map['IMPI'], rpad(content, bin_size_bytes*2))
return sw
def read_impu(self):
rec_cnt = self._scc.record_count(EF_ISIM_ADF_map['IMPU'])
impu_recs = ""
for i in range(0, rec_cnt):
(res, sw) = self._scc.read_record(EF_ISIM_ADF_map['IMPU'], i + 1)
if sw == '9000':
# Skip the inital tag value ('80') byte and get length of contents
length = int(res[2:4], 16)
content = h2s(res[4:4+(length*2)])
impu_recs += "\t%s\n" % (len(content) and content or 'Not available')
else:
impu_recs += "IMS public user identity: Can't read, response code = %s\n" % (sw)
return impu_recs
def update_impu(self, impu=None):
hex_str = ""
if impu:
hex_str = s2h(impu)
# Build TLV
tlv = TLV(['80'])
content = tlv.build({'80': hex_str})
rec_size_bytes = self._scc.record_size(EF_ISIM_ADF_map['IMPU'])
impu_tlv = rpad(content, rec_size_bytes*2)
data, sw = self._scc.update_record(EF_ISIM_ADF_map['IMPU'], 1, impu_tlv)
return sw
def read_iari(self):
rec_cnt = self._scc.record_count(EF_ISIM_ADF_map['UICCIARI'])
uiari_recs = ""
for i in range(0, rec_cnt):
(res, sw) = self._scc.read_record(EF_ISIM_ADF_map['UICCIARI'], i + 1)
if sw == '9000':
# Skip the inital tag value ('80') byte and get length of contents
length = int(res[2:4], 16)
content = h2s(res[4:4+(length*2)])
uiari_recs += "\t%s\n" % (len(content) and content or 'Not available')
else:
uiari_recs += "UICC IARI: Can't read, response code = %s\n" % (sw)
return uiari_recs
class _MagicSimBase(Card):
"""
@@ -333,7 +481,7 @@ class _MagicSimBase(Card):
r = self._scc.select_file(['3f00', '7f4d', f[0]])
rec_len = int(r[-1][28:30], 16)
tlen = int(r[-1][4:8],16)
rec_cnt = (tlen / rec_len) - 1;
rec_cnt = (tlen / rec_len) - 1
if (rec_cnt < 1) or (rec_len != f[1]):
raise RuntimeError('Bad card type')
@@ -463,7 +611,7 @@ class FakeMagicSim(Card):
r = self._scc.select_file(['3f00', '000c'])
rec_len = int(r[-1][28:30], 16)
tlen = int(r[-1][4:8],16)
rec_cnt = (tlen / rec_len) - 1;
rec_cnt = (tlen / rec_len) - 1
if (rec_cnt < 1) or (rec_len != 0x5a):
raise RuntimeError('Bad card type')
@@ -624,9 +772,9 @@ class SysmoSIMgr2(Card):
def program(self, p):
# select MF
# select MF
r = self._scc.select_file(['3f00'])
# authenticate as SUPER ADM using default key
self._scc.verify_chv(0x0b, h2b("3838383838383838"))
@@ -642,7 +790,7 @@ class SysmoSIMgr2(Card):
pdu = 'A0D43A0508' + b2h(pin)
data, sw = self._scc._tp.send_apdu(pdu)
# authenticate as ADM (enough to write file, and can set PINs)
self._scc.verify_chv(0x05, pin)
@@ -652,7 +800,7 @@ class SysmoSIMgr2(Card):
# select DF_GSM
r = self._scc.select_file(['7f20'])
# write EF.IMSI
data, sw = self._scc.update_binary('6f07', enc_imsi(p['imsi']))
@@ -674,7 +822,7 @@ class SysmoSIMgr2(Card):
# select DF_TELECOM
r = self._scc.select_file(['3f00', '7f10'])
# write EF.SMSP
if p.get('smsp'):
data, sw = self._scc.update_record('6f42', 1, lpad(p['smsp'], 80))
@@ -784,7 +932,7 @@ class SysmoUSIMSJS1(UsimCard):
data, sw = self._scc.update_record('6F40', 1, data, force_len=True)
class FairwavesSIM(Card):
class FairwavesSIM(UsimCard):
"""
FairwavesSIM
@@ -973,7 +1121,7 @@ class OpenCellsSim(Card):
# write EF.IMSI
data, sw = self._scc.update_binary('6f07', enc_imsi(p['imsi']))
class WavemobileSim(Card):
class WavemobileSim(UsimCard):
"""
WavemobileSim
@@ -1064,7 +1212,7 @@ class WavemobileSim(Card):
return None
class SysmoISIMSJA2(UsimCard):
class SysmoISIMSJA2(UsimCard, IsimCard):
"""
sysmocom sysmoISIM-SJA2
"""
@@ -1152,6 +1300,26 @@ class SysmoISIMSJA2(UsimCard):
r = self._scc.select_file(['3f00', '7f10'])
data, sw = self._scc.update_record('6f42', 1, lpad(p['smsp'], 104), force_len=True)
# EF.MSISDN
# TODO: Alpha Identifier (currently 'ff'O * 20)
# TODO: Capability/Configuration1 Record Identifier
# TODO: Extension1 Record Identifier
if p.get('msisdn') is not None:
msisdn = enc_msisdn(p['msisdn'])
content = 'ff' * 20 + msisdn + 'ff' * 2
r = self._scc.select_file(['3f00', '7f10'])
data, sw = self._scc.update_record('6F40', 1, content, force_len=True)
# EF.ACC
if p.get('acc'):
sw = self.update_acc(p['acc'])
if sw != '9000':
print("Programming ACC failed with code %s"%sw)
# Populate AIDs
self.read_aids()
# update EF-SIM_AUTH_KEY (and EF-USIM_AUTH_KEY_2G, which is
# hard linked to EF-USIM_AUTH_KEY)
self._scc.select_file(['3f00'])
@@ -1162,20 +1330,55 @@ class SysmoISIMSJA2(UsimCard):
self._scc.update_binary('6f20', p['opc'], 17)
# update EF-USIM_AUTH_KEY in ADF.ISIM
self._scc.select_file(['3f00'])
aid = self.read_aid(isim = True)
if (aid):
self._scc.select_adf(aid)
if '9000' == self.select_adf_by_aid(adf="isim"):
if p.get('ki'):
self._scc.update_binary('af20', p['ki'], 1)
if p.get('opc'):
self._scc.update_binary('af20', p['opc'], 17)
self._scc.select_file(['3f00'])
aid = self.read_aid()
if (aid):
# update EF.P-CSCF in ADF.ISIM
if self.file_exists(EF_ISIM_ADF_map['PCSCF']):
if p.get('pcscf'):
sw = self.update_pcscf(p['pcscf'])
else:
sw = self.update_pcscf("")
if sw != '9000':
print("Programming P-CSCF failed with code %s"%sw)
# update EF.DOMAIN in ADF.ISIM
if self.file_exists(EF_ISIM_ADF_map['DOMAIN']):
if p.get('ims_hdomain'):
sw = self.update_domain(domain=p['ims_hdomain'])
else:
sw = self.update_domain()
if sw != '9000':
print("Programming Home Network Domain Name failed with code %s"%sw)
# update EF.IMPI in ADF.ISIM
# TODO: Validate IMPI input
if self.file_exists(EF_ISIM_ADF_map['IMPI']):
if p.get('impi'):
sw = self.update_impi(p['impi'])
else:
sw = self.update_impi()
if sw != '9000':
print("Programming IMPI failed with code %s"%sw)
# update EF.IMPU in ADF.ISIM
# TODO: Validate IMPU input
# Support multiple IMPU if there is enough space
if self.file_exists(EF_ISIM_ADF_map['IMPU']):
if p.get('impu'):
sw = self.update_impu(p['impu'])
else:
sw = self.update_impu()
if sw != '9000':
print("Programming IMPU failed with code %s"%sw)
if '9000' == self.select_adf_by_aid():
# update EF-USIM_AUTH_KEY in ADF.USIM
self._scc.select_adf(aid)
if p.get('ki'):
self._scc.update_binary('af20', p['ki'], 1)
if p.get('opc'):
@@ -1187,6 +1390,49 @@ class SysmoISIMSJA2(UsimCard):
sw = self.update_ehplmn(p['mcc'], p['mnc'])
if sw != '9000':
print("Programming EHPLMN failed with code %s"%sw)
# update EF.ePDGId in ADF.USIM
if self.file_exists(EF_USIM_ADF_map['ePDGId']):
if p.get('epdgid'):
sw = self.update_epdgid(p['epdgid'])
else:
sw = self.update_epdgid("")
if sw != '9000':
print("Programming ePDGId failed with code %s"%sw)
# update EF.ePDGSelection in ADF.USIM
if self.file_exists(EF_USIM_ADF_map['ePDGSelection']):
if p.get('epdgSelection'):
epdg_plmn = p['epdgSelection']
sw = self.update_ePDGSelection(epdg_plmn[:3], epdg_plmn[3:])
else:
sw = self.update_ePDGSelection("", "")
if sw != '9000':
print("Programming ePDGSelection failed with code %s"%sw)
# After successfully programming EF.ePDGId and EF.ePDGSelection,
# Set service 106 and 107 as available in EF.UST
# Disable service 95, 99, 115 if ISIM application is present
if self.file_exists(EF_USIM_ADF_map['UST']):
if p.get('epdgSelection') and p.get('epdgid'):
sw = self.update_ust(106, 1)
if sw != '9000':
print("Programming UST failed with code %s"%sw)
sw = self.update_ust(107, 1)
if sw != '9000':
print("Programming UST failed with code %s"%sw)
sw = self.update_ust(95, 0)
if sw != '9000':
print("Programming UST failed with code %s"%sw)
sw = self.update_ust(99, 0)
if sw != '9000':
print("Programming UST failed with code %s"%sw)
sw = self.update_ust(115, 0)
if sw != '9000':
print("Programming UST failed with code %s"%sw)
return

View File

@@ -26,7 +26,7 @@ from pySim.utils import rpad, b2h
class SimCardCommands(object):
def __init__(self, transport):
self._tp = transport;
self._tp = transport
self._cla_byte = "a0"
self.sel_ctrl = "0000"

View File

@@ -24,10 +24,10 @@
from smartcard.CardConnection import CardConnection
from smartcard.CardRequest import CardRequest
from smartcard.Exceptions import NoCardException, CardRequestTimeoutException
from smartcard.Exceptions import NoCardException, CardRequestTimeoutException, CardConnectionException
from smartcard.System import readers
from pySim.exceptions import NoCardError
from pySim.exceptions import NoCardError, ProtocolError
from pySim.transport import LinkBase
from pySim.utils import h2i, i2h
@@ -35,7 +35,7 @@ from pySim.utils import h2i, i2h
class PcscSimLink(LinkBase):
def __init__(self, reader_number=0):
r = readers();
r = readers()
self._reader = r[reader_number]
self._con = self._reader.createConnection()

View File

@@ -25,6 +25,7 @@ from __future__ import absolute_import
import serial
import time
import os.path
from pySim.exceptions import NoCardError, ProtocolError
from pySim.transport import LinkBase
@@ -34,6 +35,8 @@ from pySim.utils import h2b, b2h
class SerialSimLink(LinkBase):
def __init__(self, device='/dev/ttyUSB0', baudrate=9600, rst='-rts', debug=False):
if not os.path.exists(device):
raise ValueError("device file %s does not exist -- abort" % device)
self._sl = serial.Serial(
port = device,
parity = serial.PARITY_EVEN,
@@ -49,7 +52,8 @@ class SerialSimLink(LinkBase):
self._atr = None
def __del__(self):
self._sl.close()
if (hasattr(self, "_sl")):
self._sl.close()
def wait_for_card(self, timeout=None, newcardonly=False):
# Direct try
@@ -117,7 +121,7 @@ class SerialSimLink(LinkBase):
rst_meth = rst_meth_map[self._rst_pin[1:]]
rst_val = rst_val_map[self._rst_pin[0]]
except:
raise ValueError('Invalid reset pin %s' % self._rst_pin);
raise ValueError('Invalid reset pin %s' % self._rst_pin)
rst_meth(rst_val)
time.sleep(0.1) # 100 ms
@@ -128,7 +132,7 @@ class SerialSimLink(LinkBase):
if not b:
return 0
if ord(b) != 0x3b:
return -1;
return -1
self._dbg_print("TS: 0x%x Direct convention" % ord(b))
while ord(b) == 0x3b:
@@ -222,7 +226,7 @@ class SerialSimLink(LinkBase):
if (to_recv == 2) and (b == '\x60'): # Ignore NIL if we have no RX data (hack ?)
continue
if not b:
break;
break
data += b
# Split datafield from SW

View File

@@ -135,6 +135,23 @@ EF_UST_map = {
109: 'MCPTT',
110: 'ePDG configuration Information for Emergency Service support',
111: 'ePDG configuration Information for Emergency Service configured',
112: 'eCall Data over IMS',
113: 'URI support for SMS-PP DOWNLOAD as defined in 3GPP TS 31.111 [12]',
114: 'From Preferred',
115: 'IMS configuration data',
116: 'TV configuration',
117: '3GPP PS Data Off',
118: '3GPP PS Data Off Service List',
119: 'V2X',
120: 'XCAP Configuration Data',
121: 'EARFCN list for MTC/NB-IOT UEs',
122: '5GS Mobility Management Information',
123: '5G Security Parameters',
124: 'Subscription identifier privacy support',
125: 'SUCI calculation by the USIM',
126: 'UAC Access Identities support',
127: 'Expect control plane-based Steering of Roaming information during initial registration in VPLMN',
128: 'Call control on PDU Session by USIM',
}
LOCI_STATUS_map = {
@@ -143,6 +160,7 @@ LOCI_STATUS_map = {
2: 'plmn not allowed',
3: 'locatation area not allowed'
}
EF_USIM_ADF_map = {
'LI': '6F05',
'ARR': '6F06',

View File

@@ -42,5 +42,28 @@ EF_IST_map = {
16: 'URI support for SMS-PP DOWNLOAD as defined in 3GPP TS 31.111 [31]',
17: 'From Preferred',
18: 'IMS configuration data',
19: 'XCAP Configuration Data'
19: 'XCAP Configuration Data',
20: 'WebRTC URI',
}
EF_ISIM_ADF_map = {
'IST': '6F07',
'IMPI': '6F02',
'DOMAIN': '6F03',
'IMPU': '6F04',
'AD': '6FAD',
'ARR': '6F06',
'PCSCF': '6F09',
'GBAP': '6FD5',
'GBANL': '6FD7',
'NAFKCA': '6FDD',
'UICCIARI': '6FE7',
'SMS': '6F3C',
'SMSS': '6F43',
'SMSR': '6F47',
'SMSP': '6F42',
'FromPreferred': '6FF7',
'IMSConfigData': '6FF8',
'XCAPConfigData': '6FFC',
'WebRTCURI': '6FFA'
}

View File

@@ -313,4 +313,14 @@ EF_SST_map = {
57: 'Multimedia Messaging Service (MMS)',
58: 'Extension 8',
59: 'MMS User Connectivity Parameters',
}
}
# 10.3.18 "EF.AD (Administrative data) "
EF_AD_mode_map = {
'00' : 'normal operation',
'80' : 'type approval operations',
'01' : 'normal operation + specific facilities',
'81' : 'type approval operations + specific facilities',
'02' : 'maintenance (off line)',
'04' : 'cell test operation',
}

View File

@@ -122,11 +122,8 @@ def enc_spn(name, hplmn_disp=False, oplmn_disp=False):
if oplmn_disp: byte1 = byte1|0x02
return i2h([byte1])+s2h(name)
def hexstr_to_fivebytearr(s):
return [s[i:i+10] for i in range(0, len(s), 10) ]
def hexstr_to_threebytearr(s):
return [s[i:i+6] for i in range(0, len(s), 6) ]
def hexstr_to_Nbytearr(s, nbytes):
return [s[i:i+(nbytes*2)] for i in range(0, len(s), (nbytes*2)) ]
# Accepts hex string representing three bytes
def dec_mcc_from_plmn(plmn):
@@ -140,9 +137,9 @@ def dec_mcc_from_plmn(plmn):
def dec_mnc_from_plmn(plmn):
ia = h2i(plmn)
digit1 = ia[2] & 0x0F # 3rd byte, LSB
digit2 = (ia[2] & 0xF0) >> 4 # 3rd byte, MSB
digit3 = (ia[1] & 0xF0) >> 4 # 2nd byte, MSB
digit1 = (ia[1] & 0xF0) >>4 # 2nd byte, MSB
digit2 = ia[2] & 0x0F # 3rd byte, LSB
digit3 = (ia[2] & 0xF0) >> 4 # 3nd byte, MSB
if digit3 == 0xF and digit2 == 0xF and digit1 == 0xF:
return 0xFFF # 4095
return derive_mnc(digit1, digit2, digit3)
@@ -177,7 +174,7 @@ def dec_xplmn_w_act(fivehexbytes):
def format_xplmn_w_act(hexstr):
s = ""
for rec_data in hexstr_to_fivebytearr(hexstr):
for rec_data in hexstr_to_Nbytearr(hexstr, 5):
rec_info = dec_xplmn_w_act(rec_data)
if rec_info['mcc'] == 0xFFF and rec_info['mnc'] == 0xFFF:
rec_str = "unused"
@@ -226,7 +223,7 @@ def dec_xplmn(threehexbytes):
def format_xplmn(hexstr):
s = ""
for rec_data in hexstr_to_threebytearr(hexstr):
for rec_data in hexstr_to_Nbytearr(hexstr, 3):
rec_info = dec_xplmn(rec_data)
if rec_info['mcc'] == 0xFFF and rec_info['mnc'] == 0xFFF:
rec_str = "unused"
@@ -252,7 +249,7 @@ def calculate_luhn(cc):
"""
Calculate Luhn checksum used in e.g. ICCID and IMEI
"""
num = map(int, str(cc))
num = list(map(int, str(cc)))
check_digit = 10 - sum(num[-2::-2] + [sum(divmod(d * 2, 10)) for d in num[::-2]]) % 10
return 0 if check_digit == 10 else check_digit
@@ -460,19 +457,62 @@ def TLV_parser(bytelist):
bytelist = bytelist[ L+2 : ]
return ret
def dec_epdgid(hexstr):
def enc_st(st, service, state=1):
"""
Decode ePDG Id to get EF.ePDGId or EF.ePDGIdEm.
See 3GPP TS 31.102 version 13.4.0 Release 13, section 4.2.102 and 4.2.104.
Encodes the EF S/U/IST/EST and returns the updated Service Table
Parameters:
st - Current value of SIM/USIM/ISIM Service Table
service - Service Number to encode as activated/de-activated
state - 1 mean activate, 0 means de-activate
Returns:
s - Modified value of SIM/USIM/ISIM Service Table
Default values:
- state: 1 - Sets the particular Service bit to 1
"""
st_bytes = [st[i:i+2] for i in range(0, len(st), 2) ]
s = ""
# Check whether the requested service is present in each byte
for i in range(0, len(st_bytes)):
# Byte i contains info about Services num (8i+1) to num (8i+8)
if service in range((8*i) + 1, (8*i) + 9):
byte = int(st_bytes[i], 16)
# Services in each byte are in order MSB to LSB
# MSB - Service (8i+8)
# LSB - Service (8i+1)
mod_byte = 0x00
# Copy bit by bit contents of byte to mod_byte with modified bit
# for requested service
for j in range(1, 9):
mod_byte = mod_byte >> 1
if service == (8*i) + j:
mod_byte = state == 1 and mod_byte|0x80 or mod_byte&0x7f
else:
mod_byte = byte&0x01 == 0x01 and mod_byte|0x80 or mod_byte&0x7f
byte = byte >> 1
s += ('%02x' % (mod_byte))
else:
s += st_bytes[i]
return s
def dec_addr_tlv(hexstr):
"""
Decode hex string to get EF.P-CSCF Address or EF.ePDGId or EF.ePDGIdEm.
See 3GPP TS 31.102 version 13.4.0 Release 13, section 4.2.8, 4.2.102 and 4.2.104.
"""
# Convert from hex str to int bytes list
epdgid_bytes = h2i(hexstr)
addr_tlv_bytes = h2i(hexstr)
s = ""
# Get list of tuples containing parsed TLVs
tlvs = TLV_parser(epdgid_bytes)
tlvs = TLV_parser(addr_tlv_bytes)
for tlv in tlvs:
# tlv = (T, L, [V])
@@ -490,29 +530,45 @@ def dec_epdgid(hexstr):
# First byte in the value has the address type
addr_type = tlv[2][0]
# TODO: Support parsing of IPv4 and IPv6
# TODO: Support parsing of IPv6
# Address Type: 0x00 (FQDN), 0x01 (IPv4), 0x02 (IPv6), other (Reserved)
if addr_type == 0x00: #FQDN
# Skip address tye byte i.e. first byte in value list
content = tlv[2][1:]
s += "\t%s # %s\n" % (i2h(content), i2s(content))
elif addr_type == 0x01: #IPv4
# Skip address tye byte i.e. first byte in value list
# Skip the unused byte in Octect 4 after address type byte as per 3GPP TS 31.102
ipv4 = tlv[2][2:]
content = '.'.join(str(x) for x in ipv4)
s += "\t%s # %s\n" % (i2h(ipv4), content)
return s
def enc_epdgid(epdg_addr, addr_type='00'):
def enc_addr_tlv(addr, addr_type='00'):
"""
Encode ePDG Id so it can be stored to EF.ePDGId or EF.ePDGIdEm.
See 3GPP TS 31.102 version 13.4.0 Release 13, section 4.2.102 and 4.2.104.
Encode address TLV object used in EF.P-CSCF Address, EF.ePDGId and EF.ePDGIdEm.
See 3GPP TS 31.102 version 13.4.0 Release 13, section 4.2.8, 4.2.102 and 4.2.104.
Default values:
- addr_type: 00 - FQDN format of ePDG Address
- addr_type: 00 - FQDN format of Address
"""
s = ""
# TODO: Encoding of IPv4 and IPv6 address
if addr_type == '00':
hex_str = s2h(epdg_addr)
# TODO: Encoding of IPv6 address
if addr_type == '00': #FQDN
hex_str = s2h(addr)
s += '80' + ('%02x' % ((len(hex_str)//2)+1)) + '00' + hex_str
elif addr_type == '01': #IPv4
ipv4_list = addr.split('.')
ipv4_str = ""
for i in ipv4_list:
ipv4_str += ('%02x' % (int(i)))
# Unused bytes shall be set to 'ff'. i.e 4th Octet after Address Type is not used
# IPv4 Address is in octet 5 to octet 8 of the TLV data object
s += '80' + ('%02x' % ((len(ipv4_str)//2)+2)) + '01' + 'ff' + ipv4_str
return s
@@ -551,21 +607,158 @@ def init_reader(opts):
"""
Init card reader driver
"""
if opts.pcsc_dev is not None:
print("Using PC/SC reader interface")
from pySim.transport.pcsc import PcscSimLink
sl = PcscSimLink(opts.pcsc_dev)
elif opts.osmocon_sock is not None:
print("Using Calypso-based (OsmocomBB) reader interface")
from pySim.transport.calypso import CalypsoSimLink
sl = CalypsoSimLink(sock_path=opts.osmocon_sock)
elif opts.modem_dev is not None:
print("Using modem for Generic SIM Access (3GPP TS 27.007)")
from pySim.transport.modem_atcmd import ModemATCommandLink
sl = ModemATCommandLink(device=opts.modem_dev, baudrate=opts.modem_baud)
else: # Serial reader is default
print("Using serial reader interface")
from pySim.transport.serial import SerialSimLink
sl = SerialSimLink(device=opts.device, baudrate=opts.baudrate)
try:
if opts.pcsc_dev is not None:
print("Using PC/SC reader interface")
from pySim.transport.pcsc import PcscSimLink
sl = PcscSimLink(opts.pcsc_dev)
elif opts.osmocon_sock is not None:
print("Using Calypso-based (OsmocomBB) reader interface")
from pySim.transport.calypso import CalypsoSimLink
sl = CalypsoSimLink(sock_path=opts.osmocon_sock)
elif opts.modem_dev is not None:
print("Using modem for Generic SIM Access (3GPP TS 27.007)")
from pySim.transport.modem_atcmd import ModemATCommandLink
sl = ModemATCommandLink(device=opts.modem_dev, baudrate=opts.modem_baud)
else: # Serial reader is default
print("Using serial reader interface")
from pySim.transport.serial import SerialSimLink
sl = SerialSimLink(device=opts.device, baudrate=opts.baudrate)
return sl
except Exception as e:
print("Card reader initialization failed with exception:\n" + str(e))
return None
return sl
def enc_ePDGSelection(hexstr, mcc, mnc, epdg_priority='0001', epdg_fqdn_format='00'):
"""
Encode ePDGSelection so it can be stored at EF.ePDGSelection or EF.ePDGSelectionEm.
See 3GPP TS 31.102 version 15.2.0 Release 15, section 4.2.104 and 4.2.106.
Default values:
- epdg_priority: '0001' - 1st Priority
- epdg_fqdn_format: '00' - Operator Identifier FQDN
"""
plmn1 = enc_plmn(mcc, mnc) + epdg_priority + epdg_fqdn_format
# TODO: Handle encoding of Length field for length more than 127 Bytes
content = '80' + ('%02x' % (len(plmn1)//2)) + plmn1
content = rpad(content, len(hexstr))
return content
def dec_ePDGSelection(sixhexbytes):
"""
Decode ePDGSelection to get EF.ePDGSelection or EF.ePDGSelectionEm.
See 3GPP TS 31.102 version 15.2.0 Release 15, section 4.2.104 and 4.2.106.
"""
res = {'mcc': 0, 'mnc': 0, 'epdg_priority': 0, 'epdg_fqdn_format': ''}
plmn_chars = 6
epdg_priority_chars = 4
epdg_fqdn_format_chars = 2
# first three bytes (six ascii hex chars)
plmn_str = sixhexbytes[:plmn_chars]
# two bytes after first three bytes
epdg_priority_str = sixhexbytes[plmn_chars:plmn_chars + epdg_priority_chars]
# one byte after first five bytes
epdg_fqdn_format_str = sixhexbytes[plmn_chars + epdg_priority_chars:plmn_chars + epdg_priority_chars + epdg_fqdn_format_chars]
res['mcc'] = dec_mcc_from_plmn(plmn_str)
res['mnc'] = dec_mnc_from_plmn(plmn_str)
res['epdg_priority'] = epdg_priority_str
res['epdg_fqdn_format'] = epdg_fqdn_format_str == '00' and 'Operator Identifier FQDN' or 'Location based FQDN'
return res
def format_ePDGSelection(hexstr):
ePDGSelection_info_tag_chars = 2
ePDGSelection_info_tag_str = hexstr[:2]
s = ""
# Minimum length
len_chars = 2
# TODO: Need to determine length properly - definite length support only
# Inconsistency in spec: 3GPP TS 31.102 version 15.2.0 Release 15, 4.2.104
# As per spec, length is 5n, n - number of PLMNs
# But, each PLMN entry is made of PLMN (3 Bytes) + ePDG Priority (2 Bytes) + ePDG FQDN format (1 Byte)
# Totalling to 6 Bytes, maybe length should be 6n
len_str = hexstr[ePDGSelection_info_tag_chars:ePDGSelection_info_tag_chars+len_chars]
# Not programmed scenario
if int(len_str, 16) == 255 or int(ePDGSelection_info_tag_str, 16) == 255:
len_chars = 0
ePDGSelection_info_tag_chars = 0
if len_str[0] == '8':
# The bits 7 to 1 denotes the number of length octets if length > 127
if int(len_str[1]) > 0:
# Update number of length octets
len_chars = len_chars * int(len_str[1])
len_str = hexstr[ePDGSelection_info_tag_chars:len_chars]
content_str = hexstr[ePDGSelection_info_tag_chars+len_chars:]
# Right pad to prevent index out of range - multiple of 6 bytes
content_str = rpad(content_str, len(content_str) + (12 - (len(content_str) % 12)))
for rec_data in hexstr_to_Nbytearr(content_str, 6):
rec_info = dec_ePDGSelection(rec_data)
if rec_info['mcc'] == 0xFFF and rec_info['mnc'] == 0xFFF:
rec_str = "unused"
else:
rec_str = "MCC: %03d MNC: %03d ePDG Priority: %s ePDG FQDN format: %s" % \
(rec_info['mcc'], rec_info['mnc'], rec_info['epdg_priority'], rec_info['epdg_fqdn_format'])
s += "\t%s # %s\n" % (rec_data, rec_str)
return s
def get_addr_type(addr):
"""
Validates the given address and returns it's type (FQDN or IPv4 or IPv6)
Return: 0x00 (FQDN), 0x01 (IPv4), 0x02 (IPv6), None (Bad address argument given)
TODO: Handle IPv6
"""
# Empty address string
if not len(addr):
return None
import sys
# Handle python3 and python2 - unicode
if sys.version_info[0] < 3:
addr_str = unicode(addr)
else:
addr_str = addr
addr_list = addr.split('.')
# Check for IPv4/IPv6
try:
import ipaddress
# Throws ValueError if addr is not correct
ipa = ipaddress.ip_address(addr_str)
if ipa.version == 4:
return 0x01
elif ipa.version == 6:
return 0x02
except Exception as e:
invalid_ipv4 = True
for i in addr_list:
# Invalid IPv4 may qualify for a valid FQDN, so make check here
# e.g. 172.24.15.300
import re
if not re.match('^[0-9_]+$', i):
invalid_ipv4 = False
break
if invalid_ipv4:
return None
fqdn_flag = True
for i in addr_list:
# Only Alpha-numeric characters and hyphen - RFC 1035
import re
if not re.match("^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)?$", i):
fqdn_flag = False
break
# FQDN
if fqdn_flag:
return 0x00
return None

View File

@@ -12,7 +12,7 @@ class DecTestCase(unittest.TestCase):
"ffffff0002",
"ffffff0001",
]
self.assertEqual(utils.hexstr_to_fivebytearr(input_str), expected)
self.assertEqual(utils.hexstr_to_Nbytearr(input_str, 5), expected)
def testDecMCCfromPLMN(self):
self.assertEqual(utils.dec_mcc_from_plmn("92f501"), 295)

View File

@@ -42,7 +42,9 @@ HPLMNAcT:
ACC: 0008
MSISDN: Not available
AD: 00000002
Administrative data: 00000002
MS operation mode: normal operation
Ciphering Indicator: disabled
SIM Service Table: ff3cc3ff030fff0f000fff03f0c0
Service 1 - CHV1 disable function
Service 2 - Abbreviated Dialling Numbers (ADN)
@@ -114,6 +116,5 @@ USIM Service Table: 01ea1ffc21360480010000
Service 64 - VGCS security
Service 65 - VBS security
ePDGId: Can't read file -- SW match failed! Expected 9000 and got 6a82.
Done !

View File

@@ -49,7 +49,9 @@ OPLMNwAcT:
HPLMNAcT: Can't read file -- SW match failed! Expected 9000 and got 6a82.
ACC: abce
MSISDN: Not available
AD: 00ffff02
Administrative data: 00ffff02
MS operation mode: normal operation
Ciphering Indicator: enabled
SIM Service Table: ff33ff0f3c00ff0f000cf0c0f0030000
Service 1 - CHV1 disable function
Service 2 - Abbreviated Dialling Numbers (ADN)
@@ -130,6 +132,5 @@ USIM Service Table: 9eff1b3c37fe5900000000
Service 53 - Extension 8
Service 55 - MMS User Connectivity Parameters
ePDGId: Can't read file -- SW match failed! Expected 9000 and got 6a82.
Done !

View File

@@ -16,7 +16,9 @@ OPLMNwAcT: Can't read file -- SW match failed! Expected 9000 and got 9404.
HPLMNAcT: Can't read file -- SW match failed! Expected 9000 and got 9404.
ACC: ffff
MSISDN: Not available
AD: 000000
Administrative data: 000000
MS operation mode: normal operation
Ciphering Indicator: disabled
SIM Service Table: ff3fff0f0300f003000c
Service 1 - CHV1 disable function
Service 2 - Abbreviated Dialling Numbers (ADN)

View File

@@ -4,4 +4,4 @@ ICCID=1122334455667788990
KI=AABBCCDDEEFFAABBCCDDEEFFAABBCCDD
OPC=12345678901234567890123456789012
IMSI=001010000000102
ADM=72273953
ADM=11111111

View File

@@ -1,7 +1,7 @@
Using PC/SC reader interface
Reading ...
Autodetected card type: sysmoISIM-SJA2
ICCID: 8988211900000000004
ICCID: 8988211900000000025
IMSI: 001010000000102
GID1: ffffffffffffffffffff
GID2: ffffffffffffffffffff
@@ -52,9 +52,11 @@ HPLMNAcT:
ffffff0000 # unused
ffffff0000 # unused
ACC: 0001
MSISDN (NPI=1 ToN=1): +1234
AD: 00000002
ACC: 0200
MSISDN (NPI=1 ToN=3): 6766266
Administrative data: 00000002
MS operation mode: normal operation
Ciphering Indicator: disabled
SIM Service Table: ff33ffff3f003f0f300cf0c3f00000
Service 1 - CHV1 disable function
Service 2 - Abbreviated Dialling Numbers (ADN)
@@ -101,12 +103,12 @@ SIM Service Table: ff33ffff3f003f0f300cf0c3f00000
Service 59 - MMS User Connectivity Parameters
EHPLMN:
00f110 # MCC: 001 MNC: 001
ffffff # unused
ffffff # unused
ffffff # unused
00f110 # MCC: 001 MNC: 001
ffffff # unused
ffffff # unused
ffffff # unused
USIM Service Table: beff9f9de73e0408400170730000002e00000000
USIM Service Table: beff9f9de73e0408400170330006002e00000000
Service 2 - Fixed Dialling Numbers (FDN)
Service 3 - Extension 2
Service 4 - Service Dialling Numbers (SDN)
@@ -154,11 +156,54 @@ USIM Service Table: beff9f9de73e0408400170730000002e00000000
Service 90 - Operator CSG Lists and corresponding indications
Service 93 - Communication Control for IMS by USIM
Service 94 - Extended Terminal Applications
Service 95 - Support of UICC access to IMS
Service 106 - ePDG configuration Information support
Service 107 - ePDG configuration Information configured
Service 122 - 5GS Mobility Management Information
Service 123 - 5G Security Parameters
Service 124 - Subscription identifier privacy support
Service 126 - UAC Access Identities support
ePDGId:
Not available
ePDGSelection:
ffffffffffff # unused
ffffffffffff # unused
ffffffffffff # unused
ffffffffffff # unused
P-CSCF:
Not available
Not available
Not available
Not available
Not available
Not available
Not available
Not available
Home Network Domain Name: Not available
IMS private user identity: Not available
IMS public user identity:
Not available
Not available
Not available
Not available
Not available
Not available
Not available
Not available
UICC IARI:
Not available
Not available
Not available
Not available
Not available
Not available
Not available
Not available
ISIM Service Table: 190200
Service 1 - P-CSCF address
Service 4 - GBA-based Local Key Establishment Mechanism

View File

@@ -54,7 +54,9 @@ HPLMNAcT:
ACC: 0008
MSISDN (NPI=1 ToN=1): +77776336143
AD: 00000002
Administrative data: 00000002
MS operation mode: normal operation
Ciphering Indicator: disabled
SIM Service Table: ff3fffff3f003f1ff00c00c0f00000
Service 1 - CHV1 disable function
Service 2 - Abbreviated Dialling Numbers (ADN)
@@ -138,6 +140,5 @@ USIM Service Table: 9e6b1dfc67f6580000
Service 53 - Extension 8
Service 55 - MMS User Connectivity Parameters
ePDGId: Can't read file -- SW match failed! Expected 9000 and got 6a82.
Done !

View File

@@ -16,7 +16,9 @@ OPLMNwAcT: Can't read file -- SW match failed! Expected 9000 and got 9404.
HPLMNAcT: Can't read file -- SW match failed! Expected 9000 and got 9404.
ACC: 0008
MSISDN: Not available
AD: 000000
Administrative data: 000000
MS operation mode: normal operation
Ciphering Indicator: disabled
SIM Service Table: ff3fff0f0f0000030000
Service 1 - CHV1 disable function
Service 2 - Abbreviated Dialling Numbers (ADN)