blob: 5e4811674261c3df41f69a080100961fba3ba0d6 [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 Welte8fe1d202021-04-11 12:31:40 +020043option_parser = argparse.ArgumentParser(prog='pySim-read',
44 description='Legacy tool for reading some parts of a SIM card',
45 formatter_class=argparse.ArgumentDefaultsHelpFormatter)
46argparse_add_reader_args(option_parser)
Alexander Chemeris6e589142013-07-04 17:34:06 +040047
Philipp Maierabc23362021-11-15 17:24:44 +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
Alexander Chemeris6e589142013-07-04 17:34:06 +040066if __name__ == '__main__':
67
68 # Parse options
Harald Welte8fe1d202021-04-11 12:31:40 +020069 opts = option_parser.parse_args()
Alexander Chemeris6e589142013-07-04 17:34:06 +040070
Vadim Yanitskiy588f3ac2018-10-27 06:30:33 +070071 # Init card reader driver
Philipp Maierff84c232020-05-12 17:24:18 +020072 sl = init_reader(opts)
Philipp Maierc8caec22021-02-22 16:07:53 +010073 if sl is None:
74 exit(1)
Alexander Chemeris6e589142013-07-04 17:34:06 +040075
76 # Create command layer
77 scc = SimCardCommands(transport=sl)
78
79 # Wait for SIM card
80 sl.wait_for_card()
81
Supreeth Herle3e6f16d2020-03-23 10:00:50 +010082 # Assuming UICC SIM
83 scc.cla_byte = "00"
84 scc.sel_ctrl = "0004"
85
86 # Testing for Classic SIM or UICC
87 (res, sw) = sl.send_apdu(scc.cla_byte + "a4" + scc.sel_ctrl + "02" + "3f00")
88 if sw == '6e00':
89 # Just a Classic SIM
90 scc.cla_byte = "a0"
91 scc.sel_ctrl = "0000"
92
Philipp Maier4210a702021-05-05 14:17:59 +020093 # Read the card
Alexander Chemeris6e589142013-07-04 17:34:06 +040094 print("Reading ...")
95
Supreeth Herle4c306ab2020-03-18 11:38:00 +010096 # Initialize Card object by auto detecting the card
Philipp Maierbb73e512021-05-05 16:14:00 +020097 card = card_detect("auto", scc) or SimCard(scc)
Supreeth Herle4c306ab2020-03-18 11:38:00 +010098
Supreeth Herle3bf43632020-03-20 20:20:27 +010099 # Read all AIDs on the UICC
100 card.read_aids()
101
Alexander Chemeris6e589142013-07-04 17:34:06 +0400102 # EF.ICCID
Supreeth Herle3566b8e2020-03-18 12:02:34 +0100103 (res, sw) = card.read_iccid()
Alexander Chemeris6e589142013-07-04 17:34:06 +0400104 if sw == '9000':
Supreeth Herle3566b8e2020-03-18 12:02:34 +0100105 print("ICCID: %s" % (res,))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400106 else:
107 print("ICCID: Can't read, response code = %s" % (sw,))
108
109 # EF.IMSI
Supreeth Herlef9762dc2020-03-18 12:05:06 +0100110 (res, sw) = card.read_imsi()
Alexander Chemeris6e589142013-07-04 17:34:06 +0400111 if sw == '9000':
Supreeth Herlef9762dc2020-03-18 12:05:06 +0100112 print("IMSI: %s" % (res,))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400113 else:
114 print("IMSI: Can't read, response code = %s" % (sw,))
115
Supreeth Herleab46d622020-03-05 15:30:22 +0100116 # EF.GID1
117 try:
Supreeth Herle98a69272020-03-18 12:14:48 +0100118 (res, sw) = card.read_gid1()
Supreeth Herleab46d622020-03-05 15:30:22 +0100119 if sw == '9000':
120 print("GID1: %s" % (res,))
121 else:
122 print("GID1: Can't read, response code = %s" % (sw,))
123 except Exception as e:
124 print("GID1: Can't read file -- %s" % (str(e),))
125
Supreeth Herle0e90e6c2020-03-05 15:33:00 +0100126 # EF.GID2
127 try:
Supreeth Herlee573ccb2020-04-01 09:21:20 +0200128 (res, sw) = card.read_binary('GID2')
Supreeth Herle0e90e6c2020-03-05 15:33:00 +0100129 if sw == '9000':
130 print("GID2: %s" % (res,))
131 else:
132 print("GID2: Can't read, response code = %s" % (sw,))
133 except Exception as e:
134 print("GID2: Can't read file -- %s" % (str(e),))
135
Alexander Chemeris6e589142013-07-04 17:34:06 +0400136 # EF.SMSP
Supreeth Herleebe6dba2020-03-19 12:08:20 +0100137 (res, sw) = card.read_record('SMSP', 1)
Alexander Chemeris6e589142013-07-04 17:34:06 +0400138 if sw == '9000':
139 print("SMSP: %s" % (res,))
140 else:
141 print("SMSP: Can't read, response code = %s" % (sw,))
142
Supreeth Herlef8299452019-06-08 07:49:08 +0200143 # EF.SPN
144 try:
Supreeth Herle846cefb2020-03-19 12:11:25 +0100145 (res, sw) = card.read_spn()
Supreeth Herlef8299452019-06-08 07:49:08 +0200146 if sw == '9000':
Supreeth Herle846cefb2020-03-19 12:11:25 +0100147 print("SPN: %s" % (res[0] or "Not available"))
Robert Falkenberg5933c3b2021-05-17 18:24:23 +0200148 print("Show in HPLMN: %s" % (res[1],))
149 print("Hide in OPLMN: %s" % (res[2],))
Supreeth Herlef8299452019-06-08 07:49:08 +0200150 else:
151 print("SPN: Can't read, response code = %s" % (sw,))
152 except Exception as e:
153 print("SPN: Can't read file -- %s" % (str(e),))
154
Philipp Maiera2650492018-07-11 23:05:58 +0200155 # EF.PLMNsel
156 try:
Supreeth Herle9efd8ef2020-03-19 12:14:10 +0100157 (res, sw) = card.read_binary('PLMNsel')
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200158 if sw == '9000':
159 print("PLMNsel: %s" % (res))
160 else:
161 print("PLMNsel: Can't read, response code = %s" % (sw,))
Philipp Maiera2650492018-07-11 23:05:58 +0200162 except Exception as e:
Vadim Yanitskiya3bb3342020-01-25 12:45:37 +0700163 print("PLMNsel: Can't read file -- " + str(e))
Philipp Maiera2650492018-07-11 23:05:58 +0200164
165 # EF.PLMNwAcT
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200166 try:
Supreeth Herle14084402020-03-19 12:42:10 +0100167 (res, sw) = card.read_plmn_act()
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200168 if sw == '9000':
Supreeth Herle14084402020-03-19 12:42:10 +0100169 print("PLMNwAcT:\n%s" % (res))
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200170 else:
171 print("PLMNwAcT: Can't read, response code = %s" % (sw,))
Philipp Maiera2650492018-07-11 23:05:58 +0200172 except Exception as e:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700173 print("PLMNwAcT: Can't read file -- " + str(e))
Philipp Maiera2650492018-07-11 23:05:58 +0200174
175 # EF.OPLMNwAcT
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200176 try:
Supreeth Herle1757b262020-03-19 12:43:11 +0100177 (res, sw) = card.read_oplmn_act()
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200178 if sw == '9000':
Supreeth Herle1757b262020-03-19 12:43:11 +0100179 print("OPLMNwAcT:\n%s" % (res))
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200180 else:
181 print("OPLMNwAcT: Can't read, response code = %s" % (sw,))
Philipp Maiera2650492018-07-11 23:05:58 +0200182 except Exception as e:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700183 print("OPLMNwAcT: Can't read file -- " + str(e))
Philipp Maiera2650492018-07-11 23:05:58 +0200184
185 # EF.HPLMNAcT
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200186 try:
Supreeth Herlea850a472020-03-19 12:44:11 +0100187 (res, sw) = card.read_hplmn_act()
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200188 if sw == '9000':
Supreeth Herlea850a472020-03-19 12:44:11 +0100189 print("HPLMNAcT:\n%s" % (res))
Denis 'GNUtoo' Carikli84d2cb32019-09-12 01:46:25 +0200190 else:
191 print("HPLMNAcT: Can't read, response code = %s" % (sw,))
Philipp Maiera2650492018-07-11 23:05:58 +0200192 except Exception as e:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700193 print("HPLMNAcT: Can't read file -- " + str(e))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400194
195 # EF.ACC
Supreeth Herled1fb6fc2020-03-19 12:45:45 +0100196 (res, sw) = card.read_binary('ACC')
Alexander Chemeris6e589142013-07-04 17:34:06 +0400197 if sw == '9000':
198 print("ACC: %s" % (res,))
199 else:
200 print("ACC: Can't read, response code = %s" % (sw,))
201
202 # EF.MSISDN
Sylvain Munaut9f138972013-07-18 10:36:51 +0200203 try:
Supreeth Herle6d66af62020-03-19 12:49:16 +0100204 (res, sw) = card.read_msisdn()
Sylvain Munaut9f138972013-07-18 10:36:51 +0200205 if sw == '9000':
Supreeth Herle6d66af62020-03-19 12:49:16 +0100206 # (npi, ton, msisdn) = res
207 if res is not None:
208 print("MSISDN (NPI=%d ToN=%d): %s" % res)
Sylvain Munaut9f138972013-07-18 10:36:51 +0200209 else:
210 print("MSISDN: Not available")
Alexander Chemeris6e589142013-07-04 17:34:06 +0400211 else:
Sylvain Munaut9f138972013-07-18 10:36:51 +0200212 print("MSISDN: Can't read, response code = %s" % (sw,))
Philipp Maierea6bdf02018-07-11 23:02:36 +0200213 except Exception as e:
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700214 print("MSISDN: Can't read file -- " + str(e))
Alexander Chemeris6e589142013-07-04 17:34:06 +0400215
Philipp Maieree908ae2019-03-21 16:21:12 +0100216 # EF.AD
Supreeth Herle52ef6752020-03-19 12:50:27 +0100217 (res, sw) = card.read_binary('AD')
Philipp Maieree908ae2019-03-21 16:21:12 +0100218 if sw == '9000':
Vadim Yanitskiydfe3dbb2020-07-28 05:26:02 +0700219 print("Administrative data: %s" % (res,))
Robert Falkenberg9d16fbc2021-04-12 11:43:22 +0200220 ad = EF_AD()
221 decoded_data = ad.decode_hex(res)
222 print("\tMS operation mode: %s" % decoded_data['ms_operation_mode'])
223 if decoded_data['ofm']:
Vadim Yanitskiydfe3dbb2020-07-28 05:26:02 +0700224 print("\tCiphering Indicator: enabled")
225 else:
226 print("\tCiphering Indicator: disabled")
Philipp Maieree908ae2019-03-21 16:21:12 +0100227 else:
228 print("AD: Can't read, response code = %s" % (sw,))
229
Supreeth Herlee26331e2020-03-20 18:50:39 +0100230 # EF.SST
Supreeth Herled3b13d02020-04-20 13:30:34 +0200231 (res, sw) = card.read_binary('SST')
Supreeth Herlee26331e2020-03-20 18:50:39 +0100232 if sw == '9000':
Supreeth Herled3b13d02020-04-20 13:30:34 +0200233 print("SIM Service Table: %s" % res)
Supreeth Herlee26331e2020-03-20 18:50:39 +0100234 # Print those which are available
Supreeth Herled3b13d02020-04-20 13:30:34 +0200235 print("%s" % dec_st(res))
Supreeth Herlee26331e2020-03-20 18:50:39 +0100236 else:
237 print("SIM Service Table: Can't read, response code = %s" % (sw,))
238
Supreeth Herle96412992020-03-22 08:20:11 +0100239 # Check whether we have th AID of USIM, if so select it by its AID
240 # EF.UST - File Id in ADF USIM : 6f38
Philipp Maierabc23362021-11-15 17:24:44 +0100241 sw = select_app("USIM", card)
Philipp Maiercba6dbc2021-03-11 13:03:18 +0100242 if sw == '9000':
herlesupreethcebf8b12021-01-21 05:57:06 +0100243 # Select USIM profile
244 usim_card = UsimCard(scc)
245
Harald Welteca673942020-06-03 15:19:40 +0200246 # EF.EHPLMN
herlesupreethcebf8b12021-01-21 05:57:06 +0100247 if usim_card.file_exists(EF_USIM_ADF_map['EHPLMN']):
248 (res, sw) = usim_card.read_ehplmn()
Harald Welteca673942020-06-03 15:19:40 +0200249 if sw == '9000':
250 print("EHPLMN:\n%s" % (res))
251 else:
252 print("EHPLMN: Can't read, response code = %s" % (sw,))
herlesupreeth4a3580b2020-09-29 10:11:36 +0200253
Supreeth Herle96412992020-03-22 08:20:11 +0100254 # EF.UST
herlesupreeth4a3580b2020-09-29 10:11:36 +0200255 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100256 if usim_card.file_exists(EF_USIM_ADF_map['UST']):
herlesupreeth4a3580b2020-09-29 10:11:36 +0200257 # res[0] - EF content of UST
258 # res[1] - Human readable format of services marked available in UST
herlesupreethcebf8b12021-01-21 05:57:06 +0100259 (res, sw) = usim_card.read_ust()
herlesupreeth4a3580b2020-09-29 10:11:36 +0200260 if sw == '9000':
261 print("USIM Service Table: %s" % res[0])
262 print("%s" % res[1])
263 else:
264 print("USIM Service Table: Can't read, response code = %s" % (sw,))
265 except Exception as e:
266 print("USIM Service Table: Can't read file -- " + str(e))
Supreeth Herle96412992020-03-22 08:20:11 +0100267
Supreeth Herleb1634db2020-03-22 10:00:43 +0100268 #EF.ePDGId - Home ePDG Identifier
269 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100270 if usim_card.file_exists(EF_USIM_ADF_map['ePDGId']):
271 (res, sw) = usim_card.read_epdgid()
herlesupreethf8232db2020-09-29 10:03:06 +0200272 if sw == '9000':
273 print("ePDGId:\n%s" % (len(res) and res or '\tNot available\n',))
274 else:
275 print("ePDGId: Can't read, response code = %s" % (sw,))
Supreeth Herleb1634db2020-03-22 10:00:43 +0100276 except Exception as e:
277 print("ePDGId: Can't read file -- " + str(e))
278
Supreeth Herle99d55552020-03-24 13:03:43 +0100279 #EF.ePDGSelection - ePDG Selection Information
280 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100281 if usim_card.file_exists(EF_USIM_ADF_map['ePDGSelection']):
282 (res, sw) = usim_card.read_ePDGSelection()
Supreeth Herle99d55552020-03-24 13:03:43 +0100283 if sw == '9000':
284 print("ePDGSelection:\n%s" % (res,))
285 else:
286 print("ePDGSelection: Can't read, response code = %s" % (sw,))
287 except Exception as e:
288 print("ePDGSelection: Can't read file -- " + str(e))
289
Supreeth Herle5ad9aec2020-03-24 17:26:40 +0100290 # Select ISIM application by its AID
Philipp Maierabc23362021-11-15 17:24:44 +0100291 sw = select_app("ISIM", card)
Philipp Maiercba6dbc2021-03-11 13:03:18 +0100292 if sw == '9000':
herlesupreethcebf8b12021-01-21 05:57:06 +0100293 # Select USIM profile
294 isim_card = IsimCard(scc)
295
Supreeth Herle5ad9aec2020-03-24 17:26:40 +0100296 #EF.P-CSCF - P-CSCF Address
297 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100298 if isim_card.file_exists(EF_ISIM_ADF_map['PCSCF']):
299 res = isim_card.read_pcscf()
Supreeth Herle5ad9aec2020-03-24 17:26:40 +0100300 print("P-CSCF:\n%s" % (len(res) and res or '\tNot available\n',))
301 except Exception as e:
302 print("P-CSCF: Can't read file -- " + str(e))
303
Supreeth Herle05b28072020-03-25 10:23:48 +0100304 # EF.DOMAIN - Home Network Domain Name e.g. ims.mncXXX.mccXXX.3gppnetwork.org
305 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100306 if isim_card.file_exists(EF_ISIM_ADF_map['DOMAIN']):
307 (res, sw) = isim_card.read_domain()
Supreeth Herle05b28072020-03-25 10:23:48 +0100308 if sw == '9000':
309 print("Home Network Domain Name: %s" % (len(res) and res or 'Not available',))
310 else:
311 print("Home Network Domain Name: Can't read, response code = %s" % (sw,))
312 except Exception as e:
313 print("Home Network Domain Name: Can't read file -- " + str(e))
314
Supreeth Herle3f67f9c2020-03-25 15:38:02 +0100315 # EF.IMPI - IMS private user identity
316 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100317 if isim_card.file_exists(EF_ISIM_ADF_map['IMPI']):
318 (res, sw) = isim_card.read_impi()
Supreeth Herle3f67f9c2020-03-25 15:38:02 +0100319 if sw == '9000':
320 print("IMS private user identity: %s" % (len(res) and res or 'Not available',))
321 else:
322 print("IMS private user identity: Can't read, response code = %s" % (sw,))
323 except Exception as e:
324 print("IMS private user identity: Can't read file -- " + str(e))
325
Supreeth Herle0c02d8a2020-03-26 09:00:06 +0100326 # EF.IMPU - IMS public user identity
327 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100328 if isim_card.file_exists(EF_ISIM_ADF_map['IMPU']):
329 res = isim_card.read_impu()
Supreeth Herle0c02d8a2020-03-26 09:00:06 +0100330 print("IMS public user identity:\n%s" % (len(res) and res or '\tNot available\n',))
331 except Exception as e:
332 print("IMS public user identity: Can't read file -- " + str(e))
333
Supreeth Herlebe3b6412020-06-01 12:53:57 +0200334 # EF.UICCIARI - UICC IARI
335 try:
herlesupreethcebf8b12021-01-21 05:57:06 +0100336 if isim_card.file_exists(EF_ISIM_ADF_map['UICCIARI']):
337 res = isim_card.read_iari()
Supreeth Herlebe3b6412020-06-01 12:53:57 +0200338 print("UICC IARI:\n%s" % (len(res) and res or '\tNot available\n',))
339 except Exception as e:
340 print("UICC IARI: Can't read file -- " + str(e))
341
Supreeth Herleee15c772020-03-22 08:58:33 +0100342 # EF.IST
343 (res, sw) = card.read_binary('6f07')
344 if sw == '9000':
345 print("ISIM Service Table: %s" % res)
346 # Print those which are available
347 print("%s" % dec_st(res, table="isim"))
348 else:
349 print("ISIM Service Table: Can't read, response code = %s" % (sw,))
350
Alexander Chemeris6e589142013-07-04 17:34:06 +0400351 # Done for this card and maybe for everything ?
Vadim Yanitskiy6727f0c2020-01-22 23:38:24 +0700352 print("Done !\n")