blob: f80509c15a935a8b4b6cb6b872a9c28f37cef921 [file] [log] [blame]
Daniel Willmannde07b952020-10-19 10:32:34 +02001#!/usr/bin/env python3
Alexander Chemeris6e589142013-07-04 17:34:06 +04002
3#
4# Utility to display some informations about a SIM card
5#
6#
7# Copyright (C) 2009 Sylvain Munaut <tnt@246tNt.com>
8# Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>
9# Copyright (C) 2013 Alexander Chemeris <alexander.chemeris@gmail.com>
10#
11# This program is free software: you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation, either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program. If not, see <http://www.gnu.org/licenses/>.
23#
24
25import hashlib
Harald Welte8fe1d202021-04-11 12:31:40 +020026import argparse
Alexander Chemeris6e589142013-07-04 17:34:06 +040027import os
28import random
29import re
30import sys
Robert Falkenberg9d16fbc2021-04-12 11:43:22 +020031from pySim.ts_51_011 import EF, DF, EF_SST_map, EF_AD
Sebastian Viviani0dc8f692020-05-29 00:14:55 +010032from pySim.ts_31_102 import EF_UST_map, EF_USIM_ADF_map
Supreeth Herle5ad9aec2020-03-24 17:26:40 +010033from pySim.ts_31_103 import EF_IST_map, EF_ISIM_ADF_map
Alexander Chemeris6e589142013-07-04 17:34:06 +040034
Alexander Chemeris6e589142013-07-04 17:34:06 +040035from pySim.commands import SimCardCommands
Harald Welte8fe1d202021-04-11 12:31:40 +020036from pySim.transport import init_reader, argparse_add_reader_args
Philipp Maierabc23362021-11-15 17:24:44 +010037from pySim.exceptions import SwMatchError
Philipp Maierbb73e512021-05-05 16:14:00 +020038from pySim.cards import card_detect, SimCard, UsimCard, IsimCard
Philipp Maierff84c232020-05-12 17:24:18 +020039from pySim.utils import h2b, swap_nibbles, rpad, dec_imsi, dec_iccid, dec_msisdn
Philipp Maiere2c59a82021-04-30 14:57:41 +020040from pySim.utils import format_xplmn_w_act, dec_st
Supreeth Herle99d55552020-03-24 13:03:43 +010041from pySim.utils import h2s, format_ePDGSelection
Alexander Chemeris6e589142013-07-04 17:34:06 +040042
Harald Weltef422eb12023-06-09 11:15:09 +020043option_parser = argparse.ArgumentParser(description='Legacy tool for reading some parts of a SIM card',
Harald Weltec91085e2022-02-10 18:05:45 +010044 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
Harald Welte8fe1d202021-04-11 12:31:40 +020045argparse_add_reader_args(option_parser)
Alexander Chemeris6e589142013-07-04 17:34:06 +040046
Philipp Maierabc23362021-11-15 17:24:44 +010047
Harald Weltec91085e2022-02-10 18:05:45 +010048def select_app(adf: str, card: SimCard):
49 """Select application by its AID"""
50 sw = 0
51 try:
52 if card._scc.cla_byte == "00":
53 data, sw = card.select_adf_by_aid(adf)
54 except SwMatchError as e:
55 if e.sw_actual == "6a82":
56 # If we can't select the file because it does not exist, we just remain silent since it means
57 # that this card just does not have an USIM application installed, which is not an error.
58 pass
59 else:
60 print("ADF." + adf + ": Can't select application -- " + str(e))
61 except Exception as e:
62 print("ADF." + adf + ": Can't select application -- " + str(e))
63
64 return sw
65
Philipp Maierabc23362021-11-15 17:24:44 +010066
Alexander Chemeris6e589142013-07-04 17:34:06 +040067if __name__ == '__main__':
68
Harald Weltec91085e2022-02-10 18:05:45 +010069 # Parse options
70 opts = option_parser.parse_args()
Alexander Chemeris6e589142013-07-04 17:34:06 +040071
Harald Weltec91085e2022-02-10 18:05:45 +010072 # Init card reader driver
73 sl = init_reader(opts)
74 if sl is None:
75 exit(1)
Alexander Chemeris6e589142013-07-04 17:34:06 +040076
Harald Weltec91085e2022-02-10 18:05:45 +010077 # Create command layer
78 scc = SimCardCommands(transport=sl)
Alexander Chemeris6e589142013-07-04 17:34:06 +040079
Harald Weltec91085e2022-02-10 18:05:45 +010080 # Wait for SIM card
81 sl.wait_for_card()
Alexander Chemeris6e589142013-07-04 17:34:06 +040082
Harald Weltec91085e2022-02-10 18:05:45 +010083 # Assuming UICC SIM
84 scc.cla_byte = "00"
85 scc.sel_ctrl = "0004"
Supreeth Herle3e6f16d2020-03-23 10:00:50 +010086
Harald Weltec91085e2022-02-10 18:05:45 +010087 # Testing for Classic SIM or UICC
88 (res, sw) = sl.send_apdu(scc.cla_byte + "a4" + scc.sel_ctrl + "02" + "3f00")
89 if sw == '6e00':
90 # Just a Classic SIM
91 scc.cla_byte = "a0"
92 scc.sel_ctrl = "0000"
Supreeth Herle3e6f16d2020-03-23 10:00:50 +010093
Harald Weltec91085e2022-02-10 18:05:45 +010094 # Read the card
95 print("Reading ...")
Alexander Chemeris6e589142013-07-04 17:34:06 +040096
Harald Weltec91085e2022-02-10 18:05:45 +010097 # Initialize Card object by auto detecting the card
98 card = card_detect("auto", scc) or SimCard(scc)
Supreeth Herle4c306ab2020-03-18 11:38:00 +010099
Harald Weltec91085e2022-02-10 18:05:45 +0100100 # Read all AIDs on the UICC
101 card.read_aids()
Supreeth Herle3bf43632020-03-20 20:20:27 +0100102
Harald Weltec91085e2022-02-10 18:05:45 +0100103 # EF.ICCID
104 (res, sw) = card.read_iccid()
105 if sw == '9000':
106 print("ICCID: %s" % (res,))
107 else:
108 print("ICCID: Can't read, response code = %s" % (sw,))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400109
Harald Weltec91085e2022-02-10 18:05:45 +0100110 # EF.IMSI
111 (res, sw) = card.read_imsi()
112 if sw == '9000':
113 print("IMSI: %s" % (res,))
114 else:
115 print("IMSI: Can't read, response code = %s" % (sw,))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400116
Harald Weltec91085e2022-02-10 18:05:45 +0100117 # EF.GID1
118 try:
119 (res, sw) = card.read_gid1()
120 if sw == '9000':
121 print("GID1: %s" % (res,))
122 else:
123 print("GID1: Can't read, response code = %s" % (sw,))
124 except Exception as e:
125 print("GID1: Can't read file -- %s" % (str(e),))
Supreeth Herleab46d622020-03-05 15:30:22 +0100126
Harald Weltec91085e2022-02-10 18:05:45 +0100127 # EF.GID2
128 try:
129 (res, sw) = card.read_binary('GID2')
130 if sw == '9000':
131 print("GID2: %s" % (res,))
132 else:
133 print("GID2: Can't read, response code = %s" % (sw,))
134 except Exception as e:
135 print("GID2: Can't read file -- %s" % (str(e),))
Supreeth Herle0e90e6c2020-03-05 15:33:00 +0100136
Harald Weltec91085e2022-02-10 18:05:45 +0100137 # EF.SMSP
138 (res, sw) = card.read_record('SMSP', 1)
139 if sw == '9000':
140 print("SMSP: %s" % (res,))
141 else:
142 print("SMSP: Can't read, response code = %s" % (sw,))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400143
Harald Weltec91085e2022-02-10 18:05:45 +0100144 # EF.SPN
145 try:
146 (res, sw) = card.read_spn()
147 if sw == '9000':
148 print("SPN: %s" % (res[0] or "Not available"))
149 print("Show in HPLMN: %s" % (res[1],))
150 print("Hide in OPLMN: %s" % (res[2],))
151 else:
152 print("SPN: Can't read, response code = %s" % (sw,))
153 except Exception as e:
154 print("SPN: Can't read file -- %s" % (str(e),))
Supreeth Herlef8299452019-06-08 07:49:08 +0200155
Harald Weltec91085e2022-02-10 18:05:45 +0100156 # EF.PLMNsel
157 try:
158 (res, sw) = card.read_binary('PLMNsel')
159 if sw == '9000':
160 print("PLMNsel: %s" % (res))
161 else:
162 print("PLMNsel: Can't read, response code = %s" % (sw,))
163 except Exception as e:
164 print("PLMNsel: Can't read file -- " + str(e))
Philipp Maiera2650492018-07-11 23:05:58 +0200165
Harald Weltec91085e2022-02-10 18:05:45 +0100166 # EF.PLMNwAcT
167 try:
168 (res, sw) = card.read_plmn_act()
169 if sw == '9000':
170 print("PLMNwAcT:\n%s" % (res))
171 else:
172 print("PLMNwAcT: Can't read, response code = %s" % (sw,))
173 except Exception as e:
174 print("PLMNwAcT: Can't read file -- " + str(e))
Philipp Maiera2650492018-07-11 23:05:58 +0200175
Harald Weltec91085e2022-02-10 18:05:45 +0100176 # EF.OPLMNwAcT
177 try:
178 (res, sw) = card.read_oplmn_act()
179 if sw == '9000':
180 print("OPLMNwAcT:\n%s" % (res))
181 else:
182 print("OPLMNwAcT: Can't read, response code = %s" % (sw,))
183 except Exception as e:
184 print("OPLMNwAcT: Can't read file -- " + str(e))
Philipp Maiera2650492018-07-11 23:05:58 +0200185
Harald Weltec91085e2022-02-10 18:05:45 +0100186 # EF.HPLMNAcT
187 try:
188 (res, sw) = card.read_hplmn_act()
189 if sw == '9000':
190 print("HPLMNAcT:\n%s" % (res))
191 else:
192 print("HPLMNAcT: Can't read, response code = %s" % (sw,))
193 except Exception as e:
194 print("HPLMNAcT: Can't read file -- " + str(e))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400195
Harald Weltec91085e2022-02-10 18:05:45 +0100196 # EF.ACC
197 (res, sw) = card.read_binary('ACC')
198 if sw == '9000':
199 print("ACC: %s" % (res,))
200 else:
201 print("ACC: Can't read, response code = %s" % (sw,))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400202
Harald Weltec91085e2022-02-10 18:05:45 +0100203 # EF.MSISDN
204 try:
205 (res, sw) = card.read_msisdn()
206 if sw == '9000':
207 # (npi, ton, msisdn) = res
208 if res is not None:
209 print("MSISDN (NPI=%d ToN=%d): %s" % res)
210 else:
211 print("MSISDN: Not available")
212 else:
213 print("MSISDN: Can't read, response code = %s" % (sw,))
214 except Exception as e:
215 print("MSISDN: Can't read file -- " + str(e))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400216
Harald Weltec91085e2022-02-10 18:05:45 +0100217 # EF.AD
218 (res, sw) = card.read_binary('AD')
219 if sw == '9000':
220 print("Administrative data: %s" % (res,))
221 ad = EF_AD()
222 decoded_data = ad.decode_hex(res)
223 print("\tMS operation mode: %s" % decoded_data['ms_operation_mode'])
224 if decoded_data['ofm']:
225 print("\tCiphering Indicator: enabled")
226 else:
227 print("\tCiphering Indicator: disabled")
228 else:
229 print("AD: Can't read, response code = %s" % (sw,))
Philipp Maieree908ae2019-03-21 16:21:12 +0100230
Harald Weltec91085e2022-02-10 18:05:45 +0100231 # EF.SST
232 (res, sw) = card.read_binary('SST')
233 if sw == '9000':
234 print("SIM Service Table: %s" % res)
235 # Print those which are available
236 print("%s" % dec_st(res))
237 else:
238 print("SIM Service Table: Can't read, response code = %s" % (sw,))
Supreeth Herlee26331e2020-03-20 18:50:39 +0100239
Harald Weltec91085e2022-02-10 18:05:45 +0100240 # Check whether we have th AID of USIM, if so select it by its AID
241 # EF.UST - File Id in ADF USIM : 6f38
242 sw = select_app("USIM", card)
243 if sw == '9000':
244 # Select USIM profile
245 usim_card = UsimCard(scc)
herlesupreethcebf8b12021-01-21 05:57:06 +0100246
Harald Weltec91085e2022-02-10 18:05:45 +0100247 # EF.EHPLMN
248 if usim_card.file_exists(EF_USIM_ADF_map['EHPLMN']):
249 (res, sw) = usim_card.read_ehplmn()
250 if sw == '9000':
251 print("EHPLMN:\n%s" % (res))
252 else:
253 print("EHPLMN: Can't read, response code = %s" % (sw,))
herlesupreeth4a3580b2020-09-29 10:11:36 +0200254
Matan Perelman777ee9e2023-05-14 08:58:50 +0300255 # EF.FPLMN
256 if usim_card.file_exists(EF_USIM_ADF_map['FPLMN']):
257 res, sw = usim_card.read_fplmn()
258 if sw == '9000':
259 print(f'FPLMN:\n{res}')
260 else:
261 print(f'FPLMN: Can\'t read, response code = {sw}')
262
Harald Weltec91085e2022-02-10 18:05:45 +0100263 # EF.UST
264 try:
265 if usim_card.file_exists(EF_USIM_ADF_map['UST']):
266 # res[0] - EF content of UST
267 # res[1] - Human readable format of services marked available in UST
268 (res, sw) = usim_card.read_ust()
269 if sw == '9000':
270 print("USIM Service Table: %s" % res[0])
271 print("%s" % res[1])
272 else:
273 print("USIM Service Table: Can't read, response code = %s" % (sw,))
274 except Exception as e:
275 print("USIM Service Table: Can't read file -- " + str(e))
Supreeth Herle96412992020-03-22 08:20:11 +0100276
Harald Weltec91085e2022-02-10 18:05:45 +0100277 # EF.ePDGId - Home ePDG Identifier
278 try:
279 if usim_card.file_exists(EF_USIM_ADF_map['ePDGId']):
280 (res, sw) = usim_card.read_epdgid()
281 if sw == '9000':
282 print("ePDGId:\n%s" %
283 (len(res) and res or '\tNot available\n',))
284 else:
285 print("ePDGId: Can't read, response code = %s" % (sw,))
286 except Exception as e:
287 print("ePDGId: Can't read file -- " + str(e))
Supreeth Herleb1634db2020-03-22 10:00:43 +0100288
Harald Weltec91085e2022-02-10 18:05:45 +0100289 # EF.ePDGSelection - ePDG Selection Information
290 try:
291 if usim_card.file_exists(EF_USIM_ADF_map['ePDGSelection']):
292 (res, sw) = usim_card.read_ePDGSelection()
293 if sw == '9000':
294 print("ePDGSelection:\n%s" % (res,))
295 else:
296 print("ePDGSelection: Can't read, response code = %s" % (sw,))
297 except Exception as e:
298 print("ePDGSelection: Can't read file -- " + str(e))
Supreeth Herle99d55552020-03-24 13:03:43 +0100299
Harald Weltec91085e2022-02-10 18:05:45 +0100300 # Select ISIM application by its AID
301 sw = select_app("ISIM", card)
302 if sw == '9000':
303 # Select USIM profile
304 isim_card = IsimCard(scc)
herlesupreethcebf8b12021-01-21 05:57:06 +0100305
Harald Weltec91085e2022-02-10 18:05:45 +0100306 # EF.P-CSCF - P-CSCF Address
307 try:
308 if isim_card.file_exists(EF_ISIM_ADF_map['PCSCF']):
309 res = isim_card.read_pcscf()
310 print("P-CSCF:\n%s" %
311 (len(res) and res or '\tNot available\n',))
312 except Exception as e:
313 print("P-CSCF: Can't read file -- " + str(e))
Supreeth Herle5ad9aec2020-03-24 17:26:40 +0100314
Harald Weltec91085e2022-02-10 18:05:45 +0100315 # EF.DOMAIN - Home Network Domain Name e.g. ims.mncXXX.mccXXX.3gppnetwork.org
316 try:
317 if isim_card.file_exists(EF_ISIM_ADF_map['DOMAIN']):
318 (res, sw) = isim_card.read_domain()
319 if sw == '9000':
320 print("Home Network Domain Name: %s" %
321 (len(res) and res or 'Not available',))
322 else:
323 print(
324 "Home Network Domain Name: Can't read, response code = %s" % (sw,))
325 except Exception as e:
326 print("Home Network Domain Name: Can't read file -- " + str(e))
Supreeth Herle05b28072020-03-25 10:23:48 +0100327
Harald Weltec91085e2022-02-10 18:05:45 +0100328 # EF.IMPI - IMS private user identity
329 try:
330 if isim_card.file_exists(EF_ISIM_ADF_map['IMPI']):
331 (res, sw) = isim_card.read_impi()
332 if sw == '9000':
333 print("IMS private user identity: %s" %
334 (len(res) and res or 'Not available',))
335 else:
336 print(
337 "IMS private user identity: Can't read, response code = %s" % (sw,))
338 except Exception as e:
339 print("IMS private user identity: Can't read file -- " + str(e))
Supreeth Herle3f67f9c2020-03-25 15:38:02 +0100340
Harald Weltec91085e2022-02-10 18:05:45 +0100341 # EF.IMPU - IMS public user identity
342 try:
343 if isim_card.file_exists(EF_ISIM_ADF_map['IMPU']):
344 res = isim_card.read_impu()
345 print("IMS public user identity:\n%s" %
346 (len(res) and res or '\tNot available\n',))
347 except Exception as e:
348 print("IMS public user identity: Can't read file -- " + str(e))
Supreeth Herle0c02d8a2020-03-26 09:00:06 +0100349
Harald Weltec91085e2022-02-10 18:05:45 +0100350 # EF.UICCIARI - UICC IARI
351 try:
352 if isim_card.file_exists(EF_ISIM_ADF_map['UICCIARI']):
353 res = isim_card.read_iari()
354 print("UICC IARI:\n%s" %
355 (len(res) and res or '\tNot available\n',))
356 except Exception as e:
357 print("UICC IARI: Can't read file -- " + str(e))
Supreeth Herlebe3b6412020-06-01 12:53:57 +0200358
Harald Weltec91085e2022-02-10 18:05:45 +0100359 # EF.IST
360 (res, sw) = card.read_binary('6f07')
361 if sw == '9000':
362 print("ISIM Service Table: %s" % res)
363 # Print those which are available
364 print("%s" % dec_st(res, table="isim"))
365 else:
366 print("ISIM Service Table: Can't read, response code = %s" % (sw,))
Supreeth Herleee15c772020-03-22 08:58:33 +0100367
Harald Weltec91085e2022-02-10 18:05:45 +0100368 # Done for this card and maybe for everything ?
369 print("Done !\n")